-
-
Notifications
You must be signed in to change notification settings - Fork 597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navigation Property not saving with BulkInsert #589
Comments
Navigation prop. support was added in 3.2.1 #139 |
Thanks. Noticed that my code works perfectly with version 3.2.5. The only test I can find regarding shadow properties has nothing to do with foreign keys, and only tests that we can manually set them and they are saved to the database. As mentioned, I know that this works. What does not work is the automatic value assignment in case the shadow property is an automatic prop created for a foreign key relation. It does seem to work in some of the versions of the package. Checked various package versions, here the result 3.2.5 works, flag "EnableShadowProperties" not yet supported The duplicate column error (package versions 3.3.6 - 3.3.8) does not occur on every entity. Could not determine why it happens on some. Simple entities with a single foreign key relation don't seem to have a problem. |
I was referring to this Test:
or in v3 branch:
If you do not plan upgrading to v5 until 6 is fully released, which is soon, then keep it on v3.2.5 if it works fine. |
I can keep it on 3.2.5 Did some more checking on this. I am noting what I found, in case it helps. From what I have seen the error might also be occuring in the 5 branch, undetected. The test ShadowFKPropertiesTest is not so very good. Occasionally the BulkInsert command inserts no records at all (silently with no error message), but there is no Assert for that in the test. And even if BulkRead() would return an empty collection, the subsequent loop would not run and the (The "context.BulkDelete(context.ItemLinks.ToList());" at the end of the tests makes that also easy to miss in the database itself.) I would prefer to just obtain the collection with dbContext.ItemLinks.ToList() to be sure, and do So instead of the following
the code should be like this
Now this "not inserting any records" does not happen for every entity type.
All of the above data is for version 3.6.1. |
I have confirmed that FK remains Null even on current version. EFCore.BulkExtensions/EFCore.BulkExtensions/SQLAdapters/SQLServer/SqlServerAdapter.cs Line 688 in ebc6d27
|
Hello there, This seems to still be an issue on v5.4.0. I used the "IncludeGraph" option link child POCOs to their parent POCO, but the FK in the children pointing to their parent is always null. It is a but special as the children are of the same type as the parent. So they are FKs pointing to the same table (see examples below). By activating "TrackingEntities", I saw that the ParentIDs are tracked in the children, but not set in DB. My current workaround is to do an BulkUpdate with the tracked FKs, but it is not ideal. Any update on this? Here is an example of the table that is used: public class Fund
{
public int Id { get; set; }
public int? UmbrellaFundId { get; set; }
public string OfficialName { get; set; }
public DateTime DataIn { get; set; }
public DateTime DataOut { get; set; }
public virtual Fund UmbrellaFund { get; set; } // this nav prop is set before bulk insert to be used to create to link to the parent
public virtual ICollection<Fund> SubFunds { get; set; } // this is the inverse of the nav prop from before, which is not used and left empty
} create table [Master].[Fund]
(
[Id] int identity (1, 1) not null,
[UmbrellaFundId] int null, -- this is the FK which is null after bulk insert, but tracked when tracking is enabled
[OfficialName] nvarchar(256) not null,
[DataIn] datetime2 generated always as row start not null,
[DataOut] datetime2 generated always as row end not null,
period for system_time (DataIn, DataOut),
constraint [PK_Fund] primary key clustered ([Id] asc),
constraint [FK_Fund_UmbrellaFund] foreign key ([UmbrellaFundId]) references [Master].[Fund] ([Id]), -- pointing to itself
) with (system_versioning = on (HISTORY_TABLE = [History].[FundHistory])); EDIT: here is the method I use to Insert&Update (simplified): public async Task<bool> BulkInsertAsync(IList<Fund> funds)
{
try
{
await using var transaction = await Context.Database.BeginTransactionAsync();
await Context.BulkInsertAsync(funds, new BulkConfig
{
SetOutputIdentity = true,
IncludeGraph = true,
TrackingEntities = true
});
var subFunds = funds.Where(f => f.UmbrellaFundId is not null).ToList();
await Context.BulkUpdateAsync(subFunds);
await transaction.CommitAsync();
return true;
}
catch (Exception e)
{
return false;
}
} |
I see the test ShadowFKPropertiesTest only covers SQL server. Is Postgres unsupported for shadow FKs? If so is there any work around other than adding the ID field directly into the parent entity? I am trying to attach existing objects as FKs to entities to insert/update. The object structure is the same as napdevs original example. |
I'm having trouble with this for current version, EFC 6, .NET 6 using {
SetOutputIdentity = true,
IncludeGraph = true,
TrackingEntities = true
} Bulk operations try to insert if I remove Eventually, however, on a loop of bulk inserts per data sets, it'll fail for a bulk insert on the parent entity for duplicate ekys |
@borisdj Shadow FK is not working for Postgres. Can you please help us out?
|
I have used EFCore.BulkExtensions for about a year (.Net Core 3.1, SQL Server 2019) and in my experience, navigation properties would always automatically be populated, even if there is no explicitly defined reference column.
For example, following simple classes:
When creating a List with properly populated "Cont" objects (with proper ID as it exists in the database) then I always had success that the customer table in the database had the implicitly created "ContinentID" column properly populated with the ID of the "Cont" object.
I upgraded to 3.6.1 and it stopped working: the ContinentID prop is always NULL for every single customer entity. The version I used before was 3.1 or thereabouts. However, downgrading back to 3.1 does not help. Tried to up- and downgrade to all sorts of version with no luck at all.
On low versions like 3.1.6 I get a different error
but does not work.
Tried to use "IncludeGraph" but conceptually, that's the other way around really - it would try to insert "Cont" objects in above scenario if not existing yet. At least that's my understanding.
I found one way around it - adding the reference column explicitly in every entity (e.g. int property ContinentID in above example in the Customer class), and manually, in my code, populate the reference prop. Then it does work properly.
But do I HAVE to go that route? I have a lot of entities.
Was there some sort of fundamental change, or a change in a related / dependent package which makes this no longer work? What is my route to handle this problem? Will an upgrade to EFCore 5 and BulkExtensions 5.x help?
I do not necessarily want to upgrade EFCore 5 since it's not LTS.
The text was updated successfully, but these errors were encountered: