namespace EgwCoreLib.Lux.Data.Repository.Admin { public class VocabolarioRepository : BaseRepository, IVocabolarioRepository { #region Public Constructors public VocabolarioRepository(IDbContextFactory ctxFactory) : base(ctxFactory) { } #endregion Public Constructors #region Public Methods /// public async Task AddAsync(VocabolarioModel entity) { await using var dbCtx = await CreateContextAsync(); await dbCtx.DbSetVocabolario.AddAsync(entity); return await dbCtx.SaveChangesAsync() > 0; } /// public async Task CloneAsync(string linguaOrig, string linguaDest) { await using var dbCtx = await CreateContextAsync(); // Wrap in transaction for atomicity await using var tx = await dbCtx.Database.BeginTransactionAsync(); try { DateTime now = DateTime.Now; // 1. Recupero i record originali var listOrig = await dbCtx.DbSetVocabolario .Where(x => x.Lingua == linguaOrig) .ToListAsync(); if (listOrig == null) { await tx.RollbackAsync(); return false; } // creo nuova lingua se non esistesse... var recLang = await dbCtx.DbSetLingua.FirstOrDefaultAsync(x => x.Lingua == linguaDest); if (recLang == null) { recLang = new LinguaModel() { Lingua = linguaDest, Note = $"Cloned from {linguaOrig}" }; await dbCtx.DbSetLingua.AddAsync(recLang); await dbCtx.SaveChangesAsync(); } // 2. Proietto nei nuovi record... var listNew = listOrig.Select(x => new VocabolarioModel() { Lingua = linguaDest, Lemma = x.Lemma, Traduzione = x.Traduzione }).ToList(); // 3. Aggiungo il range dbCtx.DbSetVocabolario.AddRange(listNew); // 5. Salvo tutto in transazione bool done = await dbCtx.SaveChangesAsync() > 0; await tx.CommitAsync(); return done; } catch { await tx.RollbackAsync(); throw; } } /// public async Task DeleteAsync(VocabolarioModel entity) { await using var dbCtx = await CreateContextAsync(); dbCtx.DbSetVocabolario.Remove(entity); return await dbCtx.SaveChangesAsync() > 0; } /// public async Task> GetAllAsync() { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetVocabolario .ToListAsync(); } /// public async Task GetByIdAsync(string lingua, string lemma) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetVocabolario .Where(x => x.Lingua == lingua && x.Lemma == lemma) .FirstOrDefaultAsync(); } /// public async Task> GetByLang(string lingua) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetVocabolario .Where(o => o.Lingua == lingua) .ToListAsync(); } /// public async Task> ListLingueAsync() { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetLingua .ToListAsync(); } /// public Dictionary GetDizionarioLinguaSync(string lingua) { using var dbCtx = _ctxFactory.CreateDbContext(); return dbCtx.DbSetVocabolario .Where(x => x.Lingua == lingua) .ToDictionary(d => d.Lemma, d => d.Traduzione); } /// public async Task> GetDizionarioLinguaAsync(string lingua) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetVocabolario .Where(x => x.Lingua == lingua) .ToDictionaryAsync(d => d.Lemma, d => d.Traduzione); } /// public bool InsertSync(VocabolarioModel entity) { using var dbCtx = _ctxFactory.CreateDbContext(); dbCtx.DbSetVocabolario.Add(entity); return dbCtx.SaveChanges() > 0; } /// public async Task UpdateAsync(VocabolarioModel entity) { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context var trackedEntity = await dbCtx.DbSetVocabolario .FirstOrDefaultAsync(x => x.Lingua == entity.Lingua && x.Lemma == entity.Lemma); if (trackedEntity != null) { // Aggiorna i valori dell'entità tracciata con quelli della nuova dbCtx.Entry(trackedEntity).CurrentValues.SetValues(entity); } else { dbCtx.DbSetVocabolario.Update(entity); } return await dbCtx.SaveChangesAsync() > 0; } /// public async Task UpsertManyAsync(List upsList) { await using var dbCtx = await CreateContextAsync(); // 1. Estrai le liste distinte di Lingue e Lemmi dai tuoi DTO var listLang = upsList.Select(d => d.Lingua).Distinct().ToList(); var listLemmi = upsList.Select(d => d.Lemma).Distinct().ToList(); // 2. SELECT SUL DB: Recupera i record che combinano queste lingue e lemmi var dbList = await dbCtx.DbSetVocabolario .Where(t => listLang.Contains(t.Lingua) && listLemmi.Contains(t.Lemma)) .ToListAsync(); // 3. FILTRO IN MEMORIA: Tieni solo le coppie esatte Lingua-Lemma passate nel DTO var listExist = dbList .Where(t => upsList.Any(d => d.Lingua == t.Lingua && d.Lemma == t.Lemma)) .ToList(); // 4. CICLO DI AGGIORNAMENTO / INSERIMENTO foreach (var dto in upsList) { // Cerca la corrispondenza sulla chiave composta var esistente = listExist .FirstOrDefault(r => r.Lingua == dto.Lingua && r.Lemma == dto.Lemma); if (esistente != null) { // Aggiorna il valore della traduzione esistente.Traduzione = dto.Traduzione; } else { // Crea il nuovo record var record = new VocabolarioModel { Lingua = dto.Lingua, Lemma = dto.Lemma, Traduzione = dto.Traduzione }; await dbCtx.DbSetVocabolario.AddAsync(record); } } // Unico salvataggio finale batched return await dbCtx.SaveChangesAsync() > 0; } #endregion Public Methods } }