EntityFramework-Extensions icon indicating copy to clipboard operation
EntityFramework-Extensions copied to clipboard

BulkSaveChanges throws "Duplicate entry for key PRIMARY" ? Even with "InsertNotExists" ?

Open genaray opened this issue 1 year ago • 1 comments

Description

Im currently testing the 6.14.3 version of this lib. Especially the BulkSaveChanges operation.

Exception

Once executed i receive this error...

      -- Failed with error: Duplicate entry '9223372036854775807' for key 'PRIMARY'



Unhandled exception. MySqlConnector.MySqlException (0x80004005): Duplicate entry '9223372036854775807' for key 'PRIMARY'
   at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 44
   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 108
   at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandB
ehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 456
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior
, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56
   at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 331
   at MySqlConnector.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in /_/src/MySqlConnector/MySqlCommand.cs:line 272
   at .(DbCommand , BulkOperation )
   at .( , DbCommand )
   at .Execute(List`1 actions)
   at .(List`1 )
   at Z.BulkOperations.BulkOperation.Execute()
   at Z.BulkOperations.BulkOperation.BulkInsert()
   at .BulkInsert[T](DbContext this, IEntityType entityType, IEnumerable`1 list, Action`1 options, SavingSelector savingSelector, Boolean forceSpecificTypeMapping)
   at .BulkInsert[T](DbContext this, IEnumerable`1 entities, Action`1 options, Boolean isBulkSaveChanges)
   at .(DbContext this, List`1 , Action`1 )
   at .(DbContext this, StateManager , IReadOnlyList`1 , Action`1 )
   at .(DbContext this, StateManager , IReadOnlyList`1 , Action`1 )
   at .(DbContext this, Action`1 , DbContext )
   at DbContextExtensions.(DbContext this, Action`1 , DbContext )
   at .BulkInsert[T](DbContext this, IEntityType entityType, IEnumerable`1 list, Action`1 options, SavingSelector savingSelector, Boolean forceSpecificTypeMapping)
   at .BulkInsert[T](DbContext this, IEnumerable`1 entities, Action`1 options, Boolean isBulkSaveChanges)
   at .(DbContext this, List`1 , Action`1 )
   at .(DbContext this, StateManager , IReadOnlyList`1 , Action`1 )
   at .(DbContext this, StateManager , IReadOnlyList`1 , Action`1 )
   at .(DbContext this, Action`1 , DbContext )
   at DbContextExtensions.BulkSaveChanges(DbContext this, Action`1 options)
   at ParallelOriginGameServer.Server.Systems.PersistenceSystem.Update(Single state) in C:\Users\Lars\Desktop\Development\ParallelOrigin\ParallelOriginGameServer\ParallelOriginGameServer\Serve
r\Systems\PersistenceSystems.cs:line 80
   at DefaultEcs.System.SequentialSystem`1.Update(T state)
   at ParallelOriginGameServer.Program.Main(String[] args) in C:\Users\Lars\Desktop\Development\ParallelOrigin\ParallelOriginGameServer\ParallelOriginGameServer\Program.cs:line 345

Code

My Code looks like this... i actually tell the operation to ignore inserts when the primary key already exists, but it doesnt work. Unfortunately i cant add my data modell, its quite large and too complex. However the .SaveChanges method is able to insert, update it perfectly fine.

 Context.BulkSaveChanges(operation => {
                    operation.IncludeGraph = true;
                    operation.InsertKeepIdentity = true;   // I usually provide my own primary keys
                    operation.InsertIfNotExists = true;      // To prevent duplicate keys ( because they were mostly already inserted, each ID is unique in my game ) 
});

Glad for any help !

genaray avatar Aug 03 '22 15:08 genaray

Hello @genaray ,

Is it possible that your list of entities to insert has multiple times the same keys? Unfortunately, this case is not supported in all providers as we only look if the key already exists in the destination table and not in entities to add.

Best Regards,

Jon

JonathanMagnan avatar Aug 04 '22 01:08 JonathanMagnan