@@ -27,6 +27,7 @@ public class CrdtMiniLcmApi(
2727 CurrentProjectService projectService ,
2828 IMiniLcmCultureProvider cultureProvider ,
2929 MiniLcmValidators validators ,
30+ LcmCrdtDbContext dbContext ,
3031 IOptions < LcmCrdtConfig > config ) : IMiniLcmApi
3132{
3233 private Guid ClientId { get ; } = projectService . ProjectData . ClientId ;
@@ -60,10 +61,24 @@ private async Task<Commit> AddChange(IChange change)
6061 return commit ;
6162 }
6263
63- private async Task < Commit > AddChanges ( IEnumerable < IChange > changes )
64+ private async Task AddChanges ( IEnumerable < IChange > changes )
6465 {
65- var commit = await dataModel . AddChanges ( ClientId , changes , commitMetadata : NewMetadata ( ) ) ;
66- return commit ;
66+ await AddChanges ( changes . Chunk ( 100 ) ) ;
67+ }
68+
69+ /// <summary>
70+ /// use when making a large number of changes at once
71+ /// </summary>
72+ /// <param name="changeChunks"></param>
73+ private async Task AddChanges ( IEnumerable < IChange [ ] > changeChunks )
74+ {
75+ await using var transaction = await dbContext . Database . BeginTransactionAsync ( ) ;
76+ foreach ( var chunk in changeChunks )
77+ {
78+ await dataModel . AddChanges ( ClientId , chunk , commitMetadata : NewMetadata ( ) , deferCommit : true ) ;
79+ }
80+ await dataModel . FlushDeferredCommits ( ) ;
81+ await transaction . CommitAsync ( ) ;
6782 }
6883
6984 public async Task < WritingSystems > GetWritingSystems ( )
@@ -403,7 +418,7 @@ private async IAsyncEnumerable<Entry> GetEntries(
403418 var complexFormComparer = cultureProvider . GetCompareInfo ( sortWs )
404419 . AsComplexFormComparer ( ) ;
405420 var entries = queryable . AsAsyncEnumerable ( ) ;
406- await foreach ( var entry in entries )
421+ await foreach ( var entry in EfExtensions . SafeIterate ( entries ) )
407422 {
408423 entry . ApplySortOrder ( complexFormComparer ) ;
409424 yield return entry ;
@@ -433,12 +448,10 @@ private async IAsyncEnumerable<Entry> GetEntries(
433448 public async Task BulkCreateEntries ( IAsyncEnumerable < Entry > entries )
434449 {
435450 var semanticDomains = await SemanticDomains . ToDictionaryAsync ( sd => sd . Id , sd => sd ) ;
436- await AddChanges (
437- entries . ToBlockingEnumerable ( )
438- . SelectMany ( entry => CreateEntryChanges ( entry , semanticDomains ) )
439- //force entries to be created first, this avoids issues where references are created before the entry is created
440- . OrderBy ( c => c is CreateEntryChange ? 0 : 1 )
441- ) ;
451+ await AddChanges ( entries . ToBlockingEnumerable ( )
452+ . SelectMany ( entry => CreateEntryChanges ( entry , semanticDomains ) )
453+ //force entries to be created first, this avoids issues where references are created before the entry is created
454+ . OrderBy ( c => c is CreateEntryChange ? 0 : 1 ) ) ;
442455 }
443456
444457 private IEnumerable < IChange > CreateEntryChanges ( Entry entry , Dictionary < Guid , SemanticDomain > semanticDomains )
0 commit comments