SEARCH-1: separator-insensitive NameSearch + OriginBreeder (Herkunft) filter
- Gerbil.NameSearch (lowercase, strip whitespace/.-_) auto-synced in ApplicationContext .SaveChanges; Gridify-filterable so 'clan kleine chaoten' matches 'Clan-Kleine-Chaoten' (client strips separators the same way). GerbilSearch.Normalize shared helper. - Gerbil.OriginBreeder (free-text Herkunft) on DTO+Input, set by the FEAT-8 import from the source Zucht (imported animals have no OriginContact). Gridify-filterable. - GET /gerbils/breeders: distinct non-empty OriginBreeder values for the Herkunft dropdown. - Migration AddSearchFields (+ NameSearch backfill SQL for existing rows).
This commit is contained in:
@@ -18,6 +18,29 @@ public class ApplicationContext : DbContext
|
||||
public DbSet<SaleContract> SaleContracts => Set<SaleContract>();
|
||||
public DbSet<BreederSettings> BreederSettings => Set<BreederSettings>();
|
||||
|
||||
// Keep Gerbil.NameSearch in sync on every save (separator-insensitive search key),
|
||||
// so it can never drift from Name regardless of which code path mutates the entity.
|
||||
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
||||
{
|
||||
SyncNameSearch();
|
||||
return base.SaveChanges(acceptAllChangesOnSuccess);
|
||||
}
|
||||
|
||||
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
|
||||
{
|
||||
SyncNameSearch();
|
||||
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||
}
|
||||
|
||||
private void SyncNameSearch()
|
||||
{
|
||||
foreach (var entry in ChangeTracker.Entries<Gerbil>())
|
||||
{
|
||||
if (entry.State is EntityState.Added or EntityState.Modified)
|
||||
entry.Entity.NameSearch = GerbilSearch.Normalize(entry.Entity.Name);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Gerbil>(e =>
|
||||
|
||||
Reference in New Issue
Block a user