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

Error comparing byte array of different size in primary key with Add or Update then SaveChanges #16888

Closed
jjxtra opened this issue Aug 1, 2019 · 3 comments · Fixed by #16970
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Milestone

Comments

@jjxtra
Copy link

jjxtra commented Aug 1, 2019

Problem

I am unable to Add and/or Update multiple entity objects when there are byte array primary key columns and the data in those columns have different lengths.

Exception

2019-08-01 09:35:36.3451|WARN|DigitalRuby.IPBan.IPBanLog|DB error, ip 99.99.99.99, source RDP, user: , source ip: 2001:3ba0:cafe:44c::1 System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: Object is not a array with the same number of elements as the array to compare it to.
Parameter name: other
   at System.Array.System.Collections.IStructuralComparable.CompareTo(Object other, IComparer comparer)
   at System.Collections.StructuralComparer.Compare(Object x, Object y)
   at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.CompareStructureValue[T](T x, T y)
   at lambda_method(Closure , Object , Object )
   at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.Compare(ModificationCommand x, ModificationCommand y)
   at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, Comparison`1 comparer, Int32 a, Int32 b)
   at System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, Comparison`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, Comparison`1 comparer)
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   --- End of inner exception stack trace ---
   at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
   at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IReadOnlyList`1 entries)+MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)

Details

The primary key has a timestamp, blob and blob field (datetime, ip, source ip). Both columns in the database have blobs of 4 and 16 byte lengths from a previous data import. So it's either having the two columns being inserted be different lengths, or having existing data in the database that has blobs of different lengths from that which is being inserted. Either way I see no way to get at this compare method and change it which is frustrating.

Steps to reproduce

Attempt to insert two entity framework object with a primary key that has byte arrays. Set the byte arrays to different lengths in the two objects. Using sqlite provider but also reproduces with sql server.

Using latest .NET core 2.2 as of 2019-07-30.

Expected behavior

Different array lengths should compare just fine when multiple objects are Added or Updated, this seems like a serious bug.

Workaround

Calling SaveChanges for each individual object after each add/update seems to resolve the issue. Having them all Added or Updated without calling SaveChanges appears to be the source of the bug.

@jjxtra jjxtra changed the title Error comparing byte array of different size Error comparing byte array of different size in primary key with insert Aug 1, 2019
@jjxtra
Copy link
Author

jjxtra commented Aug 1, 2019

My primary key:

        public DateTime Timestamp { get; set; }

        [MinLength(4)]
        [MaxLength(16)]
        public byte[] IPAddressId { get; set; }

        [MinLength(4)]
        [MaxLength(16)]
        public byte[] SourceIPAddressId { get; set; }

@jjxtra jjxtra changed the title Error comparing byte array of different size in primary key with insert Error comparing byte array of different size in primary key with Add or Update then SaveChanges Aug 1, 2019
@ajcvickers
Copy link
Contributor

Note for triage: didn't occur to me that this would throw...

var x = new byte[4];
var y = new byte[5];
StructuralComparisons.StructuralComparer.Compare(x, y);

@jjxtra
Copy link
Author

jjxtra commented Aug 2, 2019

You got it, the bug is that simple I believe

@ajcvickers ajcvickers added this to the 3.0.0 milestone Aug 5, 2019
@ajcvickers ajcvickers self-assigned this Aug 5, 2019
ajcvickers added a commit that referenced this issue Aug 5, 2019
Fixes #16888

Note that `StructuralEqualityComparer.Equals` does not suffer from this problem.
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Aug 5, 2019
ajcvickers added a commit that referenced this issue Aug 6, 2019
Fixes #16888

Note that `StructuralEqualityComparer.Equals` does not suffer from this problem.
@ajcvickers ajcvickers modified the milestones: 3.0.0, 3.0.0-preview9 Aug 21, 2019
@ajcvickers ajcvickers modified the milestones: 3.0.0-preview9, 3.0.0 Nov 11, 2019
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants