@@ -153,7 +153,7 @@ public async Task<int> BulkUpdateAsync<T>(
153153 options . PropertiesToUpdate . DeterminePropertiesForUpdate ( entityType , null ) ,
154154 sqliteOptions . AutoIncrementBehavior ) ;
155155 var tableName = entityType . GetTableName ( )
156- ?? throw new Exception ( $ "The entity '{ entityType . Name } ' has no table name.") ;
156+ ?? throw new Exception ( $ "The entity '{ entityType . Name } ' has no table name.") ;
157157
158158 return await ExecuteBulkOperationAsync ( entities , entityType . GetSchema ( ) , tableName , ctx , cancellationToken ) ;
159159 }
@@ -180,7 +180,7 @@ public async Task<int> BulkInsertOrUpdateAsync<T>(
180180 sqliteOptions . PropertiesToUpdate . DeterminePropertiesForUpdate ( entityType , true ) ,
181181 sqliteOptions . AutoIncrementBehavior ) ;
182182 var tableName = entityType . GetTableName ( )
183- ?? throw new Exception ( $ "The entity '{ entityType . Name } ' has no table name.") ;
183+ ?? throw new Exception ( $ "The entity '{ entityType . Name } ' has no table name.") ;
184184
185185 return await ExecuteBulkOperationAsync ( entities , entityType . GetSchema ( ) , tableName , ctx , cancellationToken ) ;
186186 }
@@ -196,6 +196,11 @@ private async Task<int> ExecuteBulkOperationAsync<T>(
196196
197197 try
198198 {
199+ // Execute bulk operations within a transaction, otherwise SQLite will start a new transaction for every statement
200+ await using var tx = _ctx . Database . CurrentTransaction == null
201+ ? await _ctx . Database . BeginTransactionAsync ( cancellationToken ) . ConfigureAwait ( false )
202+ : null ;
203+
199204 var tableIdentifier = _sqlGenerationHelper . DelimitIdentifier ( tableName , schema ) ;
200205
201206 using var reader = bulkOperationContext . CreateReader ( entitiesOrValues ) ;
@@ -207,6 +212,9 @@ private async Task<int> ExecuteBulkOperationAsync<T>(
207212 numberOfAffectedRows += await ExecuteBulkOperationForSeparatedOwnedEntitiesAsync ( ( IReadOnlyList < object > ) readEntities , bulkOperationContext , cancellationToken ) ;
208213 }
209214
215+ if ( tx is not null )
216+ await tx . CommitAsync ( cancellationToken ) ;
217+
210218 return numberOfAffectedRows ;
211219 }
212220 finally
@@ -228,7 +236,7 @@ private async Task<int> ExecuteBulkOperationForSeparatedOwnedEntitiesAsync(
228236 foreach ( var childContext in parentBulkOperationContext . GetChildren ( parentEntities ) )
229237 {
230238 var childTableName = childContext . EntityType . GetTableName ( )
231- ?? throw new InvalidOperationException ( $ "The entity '{ childContext . EntityType . Name } ' has no table name.") ;
239+ ?? throw new InvalidOperationException ( $ "The entity '{ childContext . EntityType . Name } ' has no table name.") ;
232240
233241 numberOfAffectedRows += await ExecuteBulkOperationAsync ( childContext . Entities ,
234242 childContext . EntityType . GetSchema ( ) ,
@@ -416,7 +424,7 @@ public async Task TruncateTableAsync(Type type, CancellationToken cancellationTo
416424 {
417425 var entityType = _ctx . Model . GetEntityType ( type ) ;
418426 var tableName = entityType . GetTableName ( )
419- ?? throw new InvalidOperationException ( $ "The entity '{ entityType . Name } ' has no table name.") ;
427+ ?? throw new InvalidOperationException ( $ "The entity '{ entityType . Name } ' has no table name.") ;
420428
421429 var tableIdentifier = _sqlGenerationHelper . DelimitIdentifier ( tableName , entityType . GetSchema ( ) ) ;
422430 var truncateStatement = $ "DELETE FROM { tableIdentifier } ;";
0 commit comments