private async Task <T> AddOrUpdateItem <T>(T item, Func <T, object[]> keysFunc, UpdateFunc <T> updater) where T : class { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (keysFunc == null) { throw new ArgumentNullException(nameof(keysFunc)); } if (updater == null) { throw new ArgumentNullException(nameof(updater)); } // Try to find the item var foundItem = await _context.Set <T>().FindAsync(keysFunc(item)); if (foundItem != null) { var entry = _context.Entry(foundItem); if (entry.State == EntityState.Added) { return(foundItem); } entry.State = EntityState.Modified; updater(foundItem, item, entry); return(foundItem); } _context.Add(item); return(item); }
/// <inheritdoc /> public virtual async Task <int> AddOrUpdate(T obj) { var result = await _context.Set <T>() .Upsert(obj) .WhenMatched(Updater) .RunAsync(); _context.Database.CloseConnection(); return(result); }
/// <inheritdoc /> public async Task Invoke(PerformContext context) { List <Exception> errors = new List <Exception>(); context.WriteLine($"> Fetch all prime items"); var primeItems = await _context.Set <PrimeItem>() .Include(item => item.PrimePartIngredients) .ThenInclude(i => i.PrimePart) .Include(part => part.PrimePartIngredients) .ThenInclude(i => i.RelicDrops) .ThenInclude(drop => drop.Relic) .Include(item => item.IngredientsGroups) .ThenInclude(g => g.ResourceIngredients) .ThenInclude(i => i.Resource) .ToArrayAsync(); var primeItemsCount = primeItems.Length; context.WriteLine($"< Found {primeItemsCount} items"); context.WriteLine($"> Start fetching data per item"); var progressBar = context.WriteProgressBar(); var count = 0; foreach (var item in primeItems) { try { var itemData = await _itemScraper.GetData(item.WikiUrl); var toSave = await _persister.AddOrUpdatePrimeItem(item, itemData); } catch (Exception ex) { errors.Add(ex); context.SetTextColor(ConsoleTextColor.Red); context.WriteLine("Error occured when trying to parse " + item.Name); context.WriteLine(ex); context.WriteLine(""); context.ResetTextColor(); } count++; progressBar.SetValue(100 * count / primeItemsCount); } progressBar.SetValue(100); context.WriteLine($"< Done setting item data"); context.WriteLine($"> Saving data"); var rowsChanged = await _context.SaveChangesAsync(); context.WriteLine($"< Data saved: {rowsChanged} rows changed"); if (errors.Count > 0) { context.SetTextColor(ConsoleTextColor.Red); throw new AggregateException(errors); } }
public async Task SaveItemData(int primeItemId, string url) { // Arrange var primeItem = await _context.Set <PrimeItem>() .Include(i => i.PrimePartIngredients) .ThenInclude(i => i.PrimePart) .ThenInclude(p => p.Image) .Include(i => i.PrimePartIngredients) .ThenInclude(i => i.RelicDrops) .ThenInclude(r => r.Relic) .Include(i => i.IngredientsGroups) .ThenInclude(g => g.ResourceIngredients) .ThenInclude(i => i.Resource) .FirstOrDefaultAsync(i => i.Id == primeItemId); //Act var data = await _sut.GetData(url); await _persister.AddOrUpdatePrimeItem(primeItem, data); await _context.SaveChangesAsync(); }