Skip to content
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

BulkInsertOrUpdate fails when using SetOutputNonIdentityColumns == false and PreserveInsertOrder #47

Closed
videokojot opened this issue Oct 15, 2023 · 0 comments

Comments

@videokojot
Copy link
Owner

tracking issue for:]
https://github.com/borisdj/EFCore.BulkExtensions/issues/1250

copy of the issue:

When using custom UpdateByColumns with:

c.SetOutputIdentity = true; c.UpdateByProperties = new List { nameof(Item2.StringProperty), nameof(Item2.Name) }; c.PreserveInsertOrder = true; c.SetOutputNonIdentityColumns = false;

the insert or update works, but then the library throws on setting the output indentity. See example:

    [Fact]
    public void BulkInsertOrUpdate_WithOutputIdentity_FailsWhenSetOnlyIdentity()
    {
        using var db = GetTestContext();

        var newItem = new Item2()
        {
            StringProperty = "newItem",
            GuidProperty = new Guid("9f71ff93-2326-44d3-acb6-95b5d0566d68"),
            Name = "newName",
        };

        var ensureList = new[] { newItem, };

        // Bug in library causes null reference in case of BulkInsertUpdate with:
        // OutputIdentity == true && SetOutputNonIdentityColumns == false
        var exception = Assert.ThrowsAny<NullReferenceException>(() => db.BulkInsertOrUpdate(ensureList,
            c =>
            {
                c.SetOutputIdentity = true;
                c.UpdateByProperties = new List<string> { nameof(Item2.StringProperty), nameof(Item2.Name) };
                c.PreserveInsertOrder = true;
                c.SetOutputNonIdentityColumns = false;
            }));

        // Exception comes from place of the bug:
        Assert.Contains("EFCore.BulkExtensions.TableInfo.UpdateEntitiesIdentity", exception.StackTrace);
        
        var fromDb = db.Items2.SingleOrDefault(x => x.GuidProperty == newItem.GuidProperty);
        Assert.NotNull(fromDb); // Item was inserted!
    }

Why this happens?

Because code here:

https://github.com/borisdj/EFCore.BulkExtensions/blob/89e3ff2d0516a0d1e640758830b9826a451228e5/EFCore.BulkExtensions/TableInfo.cs#L1098

Treats objects from output table as full entities (Item, User etc) instead of just ids (long, int - because of SetOutputNonIdentityColumns=false).

Proposed solution(s):

  1. Add post validation of bulk config and forbid this combination of settings.
  2. Fix the code in TableInfo.cs. This is more complicated as it would mean to rely on the order of the output table (instead of dictionary with custom primary key as it is done now). But I can do it. Is there any reason why you do not rely on the order of the output table (and use the dictionary)?

I will happily add PR with nice tests if you agree, since we already do something simmilar in our fork.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant