PawelGerr / Thinktecture.EntityFrameworkCore

These libraries extend Entity Framework Core by a few features to make it easier to work with EF and for easier integration testing or to get more performance in some special cases.
https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore
BSD 3-Clause "New" or "Revised" License
61 stars 17 forks source link

Thinktecture.EntityFrameworkCore.BulkOperations throws exception when excluding properties #58

Open herascu opened 4 months ago

herascu commented 4 months ago

When trying to set the argument to exclude properties on BulkInsert, this exception gets thrown: Complex projections are not supported. Current expression: value(Program+<>c__DisplayClass0_0).propertiesToExclude at Thinktecture.BulkOperationsExpressionExtensions.ExtractMember(ParameterExpression paramExpression, MemberExpression memberAccess) at Thinktecture.BulkOperationsExpressionExtensions.ExtractMembers(List1 members, ParameterExpression paramExpression, Expression body) at Thinktecture.BulkOperationsExpressionExtensions.ExtractMembers[T](Expression1 projection) at Thinktecture.EntityFrameworkCore.BulkOperations.IEntityPropertiesProvider.Exclude[T](Expression`1 projection)

Sample code to replicate - simple C# console app with latest EF Core 8 and SQL Server 2019: var entities = new List<DataTable>(); Expression<Func<DataTable, object>> propertiesToExclude = p => p.RowDateTime; var propertiesToInsertValue = IEntityPropertiesProvider.Exclude<DataTable>(_ => propertiesToExclude); var options = new SqlServerBulkInsertOptions { PropertiesToInsert =propertiesToInsertValue, EnableStreaming = true, BulkCopyTimeout = TimeSpan.FromMinutes(5) }; await DbContext.BulkInsertAsync(entities, options);

public class DataTable { public int Id { get; set; } public string Name { get; set; } public DateTime RowDateTime { get; set; } }

PawelGerr commented 4 months ago

In your code example you provide a delegate which returns a delegate:

Expression<Func<DataTable, object>> propertiesToExclude = p => p.RowDateTime;
var propertiesToInsertValue = IEntityPropertiesProvider.Exclude<DataTable>(_ => propertiesToExclude);

// which is something like this:
var propertiesToInsertValue = IEntityPropertiesProvider.Exclude<DataTable>(_ => (p => p.RowDateTime));

The method exclude expects a property or an (anon) object:

var propertiesToInsertValue = IEntityPropertiesProvider.Exclude<DataTable>(p => p.RowDateTime);

// or
var propertiesToInsertValue = IEntityPropertiesProvider.Exclude<DataTable>(p => new { p.RowDateTime });