private async Task NormalizeAndSave(List <SaleDenormalizedModel> salesDenormal) { List <Region> regions = salesDenormal.Select(s => s.Region).Distinct().Select(s => new Region() { Name = s }).ToList(); await regionRepository.BulkMergeAsync(regions, options => options.ColumnPrimaryKeyExpression = r => r.Name); List <Country> countries = salesDenormal.GroupBy(s => s.Country). Select(s => new Country() { Name = s.Key, Region = regions.FirstOrDefault(r => r.Name == s.FirstOrDefault()?.Region) }).ToList(); await countryRepository.BulkMergeAsync(countries, options => options.ColumnPrimaryKeyExpression = c => c.Name); List <ItemType> itemTypes = salesDenormal.Select(s => s.ItemType).Distinct().Select(s => new ItemType() { Name = s }).ToList(); await itemTypeRepository.BulkMergeAsync(itemTypes, options => options.ColumnPrimaryKeyExpression = i => i.Name); List <Sale> sales = salesDenormal.Select(s => new Sale() { Country = countries.FirstOrDefault(r => r.Name == s.Country), ItemType = itemTypes.FirstOrDefault(t => t.Name == s.ItemType), SalesChanel = Enum.Parse <SalesChanel>(s.SalesChanel), OrderDate = DateTime.ParseExact(s.OrderDate, "M/d/yyyy", CultureInfo.InvariantCulture), OrderPriority = Enum.Parse <OrderPriority>(s.OrderPriority), ShipDate = DateTime.ParseExact(s.ShipDate, "M/d/yyyy", CultureInfo.InvariantCulture), UnitCost = decimal.Parse(s.UnitCost, CultureInfo.InvariantCulture), UnitPrice = decimal.Parse(s.UnitPrice, CultureInfo.InvariantCulture), UnitsSold = int.Parse(s.UnitsSold), OrderId = int.Parse(s.OrderId) }).ToList(); await saleRepository.BulkMergeAsync(sales, options => options.ColumnPrimaryKeyExpression = s => s.OrderId); }