What is the best way to update multiple records in a list to speed up processing?
Currently, I'm updating about 15000 products, each with 3 different price sets and it takes the whole day to complete.
I need to update the prices all at once in code side, then commit those changes to the database in 1 go, instead of fetching each inventory item, updating its values, then attaching it to the context. Every single fetch is causing the delays.
Code
public void UpdatePricesFromInventoryList(IList<Domain.Tables.Inventory> invList)
{
var db = new UniStockContext();
foreach (var inventory in invList)
{
Domain.Tables.Inventory _inventory = db.Inventories
.Where(x => x.InventoryID == inventory.InventoryID)
.FirstOrDefault();
if (inventory.Cost.HasValue)
_inventory.Cost = inventory.Cost.Value;
else
_inventory.Cost = 0;
foreach (var inventoryPrices in inventory.AccInventoryPrices)
{
foreach (var _inventoryPrices in _inventory.AccInventoryPrices)
{
if (_inventoryPrices.AccInventoryPriceID == inventoryPrices.AccInventoryPriceID)
{
_inventoryPrices.ApplyDiscount = inventoryPrices.ApplyDiscount;
_inventoryPrices.ApplyMarkup = inventoryPrices.ApplyMarkup;
if (inventoryPrices.Price.HasValue)
_inventoryPrices.Price = inventoryPrices.Price.Value;
else
_inventoryPrices.Price = _inventory.Cost;
if (inventoryPrices.OldPrice.HasValue)
{
_inventoryPrices.OldPrice = inventoryPrices.OldPrice;
}
}
}
}
db.Inventories.Attach(_inventory);
db.Entry(_inventory).State = System.Data.Entity.EntityState.Modified;
}
db.SaveChanges();
db.Dispose();
}
I've also tried working my code according to this SOQ Entity Framework update/insert multiple entities and it gave me and error. Here are the details:
Code:
public void UpdatePricesFromInventoryListBulk(IList<Domain.Tables.Inventory> invList)
{
var accounts = new List<Domain.Tables.Inventory>();
var db = new UniStockContext();
db.Configuration.AutoDetectChangesEnabled = false;
foreach (var inventory in invList)
{
accounts.Add(inventory);
if (accounts.Count % 1000 == 0)
{
db.Set<Domain.Tables.Inventory>().AddRange(accounts);
accounts = new List<Domain.Tables.Inventory>();
db.ChangeTracker.DetectChanges();
db.SaveChanges();
db.Dispose();
db = new UniStockContext();
}
}
db.Set<Domain.Tables.Inventory>().AddRange(accounts);
db.ChangeTracker.DetectChanges();
db.SaveChanges();
db.Dispose();
}
Error:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.