Using EFCore 3.1 with the library EFCore.BulkExtensions 3.6.1 (latest version for EFCore 3.1).
Database server is SQL Server 2019.
Here is code to reproduce the error.
A simple Customer class with a navigation property from another class:
public class Customer
{
public int ID { get; set; }
public String Name { get; set; }
public Cont Continent { get; set; }
}
public class Cont
{
public int ID { get; set; }
public String Name { get; set; }
}
When I try to insert entities into Customers with populated navigation properties using the "BulkInsert" method from the EFCore.BulkExtension library, the value of the navigation props do not get saved to the database:
Customer cust1 = new Customer
{
Continent = contList.Find(x => x.Name == "Europe"),
Name = "Wesson Co, Ltd."
};
Customer cust2 = new Customer
{
Continent = contList.Find(x => x.Name == "Asia"),
Name = "Tiranha, Inc."
};
// (checking the "Continent" props here shows them to be properly populated)
List<Customer> CustomerList = new List<Customer> { cust1, cust2 };
dbContext.BulkInsert(CustomerList);
The result is that the "ContinentID" column in the database is NULL.
Alternate way, as usual with the EF Core SaveChanges() works - change the last two lines to:
dbContext.Customers.AddRange(cust1, cust2);
dbContext.SaveChanges();
This works totally fine. But I have to insert a million records and SaveChanges() has a horrible performance for that scenario.
Is there anything I am doing wrong?
Using another (lower) version of the BulkExtension does not help. Higher versions won't work as they all target EFCore 5 with NetStandard 2.1 which my project does not currently support.
Could not find any hint or mention of navigation props related info in the EFCore.BulkExtension documentation.
Looking for what SQL is being sent only shows me a query like this
INSERT INTO dbo.Customers (ContinentID, Name) VALUES @p1, @p2
so it is up to BulkExtensions.BulkInsert() to place the values correctly, which it seemingly does not.
The point is that similar code has been working for 6 months, and now with a simple scenario as the above it won't, for any version of the BulkExtension library. So it is likley there must be something wrong with my code or my approach, but cannot find it.
UPDATE
Downgrading the package EFCore.BulkExtensions to 3.1.6 gives me a different error. Still does not work but here is the error:
System.InvalidOperationException : The given value 'Customer' of type String from the data source cannot be converted to type int for Column 2 [ContinentID] Row 1.
----> System.FormatException : Failed to convert parameter value from a String to a Int32.
----> System.FormatException : Input string was not in a correct format.
As it stands right now, this is a bug in the EFCore.BulkExtensions library - versions 3.2.1 through 3.3.5 will handle it (mostly) correctly, versions 3.3.6 - 3.6.1 do not.
Use version 3.3.5 for the most stable result, as of this writing.
(No data on version 5.x for EFCore 5)