@@ -517,7 +517,10 @@ public async Task<Entry> CreateEntry(Entry entry, CreateEntryOptions? options =
517517 {
518518 options ??= CreateEntryOptions . Everything ;
519519 await using var repo = await repoFactory . CreateRepoAsync ( ) ;
520- await AssignHomographNumber ( entry , repo ) ;
520+ if ( entry . HomographNumber == 0 )
521+ {
522+ await AssignHomographNumber ( entry , repo ) ;
523+ }
521524 await AddChanges ( [
522525 new CreateEntryChange ( entry ) ,
523526 ..await entry . Senses . ToAsyncEnumerable ( )
@@ -623,10 +626,9 @@ private async ValueTask<bool> IsEntryDeleted(Guid id)
623626 }
624627
625628 /// <summary>
626- /// Ensures homograph numbers are consistent when creating an entry.
627- /// Always queries entries in the same "homograph scope" (same headword + SecondaryOrder)
628- /// so that a lone existing entry at 0 gets promoted to 1 when a second entry arrives.
629- /// Explicit (non-zero) HomographNumbers are trusted as-is (FLEx handles correctness).
629+ /// When creating a new entry whose HomographNumber is 0, find entries in the same
630+ /// "homograph scope" (same headword + SecondaryOrder) and assign the next number.
631+ /// If a lone existing entry has HomographNumber 0, promote it to 1.
630632 /// </summary>
631633 private async Task AssignHomographNumber ( Entry entry , MiniLcmRepository repo )
632634 {
@@ -637,26 +639,23 @@ private async Task AssignHomographNumber(Entry entry, MiniLcmRepository repo)
637639 var newHeadword = entry . Headword ( wsId ) ;
638640 if ( string . IsNullOrEmpty ( newHeadword ) ) return ;
639641
640- // Get the SecondaryOrder for the new entry's MorphType (fall back to Stem's SecondaryOrder)
641- var morphTypeLookup = await repo . MorphTypes . ToDictionaryAsyncEF ( m => m . Kind ) ;
642- var stemSecondaryOrder = morphTypeLookup . TryGetValue ( MorphTypeKind . Stem , out var stemMt )
643- ? stemMt . SecondaryOrder
644- : 0 ;
645- var newSecondaryOrder = morphTypeLookup . TryGetValue ( entry . MorphType , out var mt )
646- ? mt . SecondaryOrder
647- : stemSecondaryOrder ;
648-
649- // Query entries with the same headword in the default vernacular WS, then filter by SecondaryOrder
650- var matchingEntries = ( await repo . Entries
651- . Where ( e => e . Id != entry . Id && e . Headword ( wsId ) == newHeadword )
652- . Select ( e => new { e . Id , e . HomographNumber , e . MorphType } )
653- . ToListAsyncLinqToDB ( ) )
654- . Where ( e =>
655- {
656- var so = morphTypeLookup . TryGetValue ( e . MorphType , out var eMt ) ? eMt . SecondaryOrder : stemSecondaryOrder ;
657- return so == newSecondaryOrder ;
658- } )
659- . ToList ( ) ;
642+ // Single DB query: join MorphTypes for SecondaryOrder filtering (same pattern as Sorting.cs)
643+ var morphTypes = repo . MorphTypes . ToLinqToDB ( ) ;
644+ var stemOrder = morphTypes . Where ( m => m . Kind == MorphTypeKind . Stem ) . Select ( m => m . SecondaryOrder ) ;
645+ var newSecondaryOrder = morphTypes
646+ . Where ( m => m . Kind == entry . MorphType )
647+ . Select ( m => ( int ? ) m . SecondaryOrder ) . FirstOrDefault ( )
648+ ?? stemOrder . FirstOrDefault ( ) ;
649+
650+ var matchingEntries = await (
651+ from e in repo . Entries
652+ where e . Id != entry . Id && e . Headword ( wsId ) == newHeadword
653+ let so = morphTypes . Where ( m => m . Kind == e . MorphType )
654+ . Select ( m => ( int ? ) m . SecondaryOrder ) . FirstOrDefault ( )
655+ ?? stemOrder . FirstOrDefault ( )
656+ where so == newSecondaryOrder
657+ select new { e . Id , e . HomographNumber }
658+ ) . ToListAsyncLinqToDB ( ) ;
660659
661660 if ( matchingEntries . Count == 0 ) return ;
662661
@@ -671,9 +670,6 @@ private async Task AssignHomographNumber(Entry entry, MiniLcmRepository repo)
671670 maxHomograph = 1 ;
672671 }
673672
674- // Explicit (non-zero) HomographNumber — trust it as-is
675- if ( entry . HomographNumber != 0 ) return ;
676-
677673 entry . HomographNumber = maxHomograph + 1 ;
678674 }
679675
0 commit comments