我想创建一个函数来接受已经设置了属性的对象列表,并对它们进行批量更新或插入,只对数据库进行1次调用。
(更新)以下是工作版本:
public static void BatchInsertProducts(IList<Product> productList)
{
using (var context = new DbContext())
{
context.Products.AddRange(productList);
context.SaveChanges();
}
}
这是我尝试根据ID更新或插入多个项目。我不认为我可以在这里使用AddRange,所以我尝试了这种方式,我收到了一个错误:
public static void SaveMultipleProducts(IList<Product> productList)
{
using (var context = new DbContext())
{
foreach (Account p in productList)
{
if (p.ID == 0)
{
context.Entry(p).State = EntityState.Added;
p.InsertUserId = "jtunney";
p.InsertDate = DateTime.Now;
}
else
{
context.Entry(p).State = EntityState.Modified;
p.UpdateUserId = "jtunney";
p.UpdateDate = DateTime.Now;
}
}
context.SaveChanges();
}
}
答案 0 :(得分:2)
删除了foreach循环,将JSON.stringify
更改为IList<Product>
:
IEnumerable<Product>
保存多重的一种方法:
public static void BatchInsertProducts(IEnumerable<Product> productList)
{
using (var context = new DbContext())
{
context.Products.AddRange(productList);
context.SaveChanges();
}
}
另一种方式:
public static void SaveMultipleProducts(IEnumerable<Product> productList)
{
using (var context = new DbContext())
{
foreach (Account p in productList)
{
p.InsertUserId="jtunney";
p.InsertDate=DateTime.Now;
context.Entry(p).State=p.Id==0?EntityState.Added:EntityState.Modified;
}
context.SaveChanges();
}
}
答案 1 :(得分:1)
没有必要为每个产品调用Save方法。如果您获得产品并使用相同的DbContext保存,您只需要保存一次,然后它将保存您的所有修改。
想象
List<Product> products = Context.Product.ToList();
foreach(var product in products)
{
product.Price = new Random().Next();
}
Context.Product.SaveChanges();
此代码正在修改列表中所有产品的价格,但是由于我们使用相同的上下文来检索结果,而EF implements Tracking通过一次调用SaveChanges来保存修改,这已经足够了
对于bulkInserts
使用实体框架http://www.entityframeworktutorial.net/EntityFramework6/addrange-removerange.aspx中的AddRange方法,或者您可以尝试使用此库https://efbulkinsert.codeplex.com/。我听说过,但我从未使用过它
答案 2 :(得分:0)
这与其他方法有点不同。
public static DbContext BatchInsertProducts(DbContext context,IList<Product> productList)
{
context.Configuration.AutoDetectChangesEnabled = false;
for (int i = 0; i < lobbies.Count; i += 100)
{
context.Set<Product>().AddRange(lobbies.GetRange(i, Math.Min(100, lobbies.Count - i)));
context.Products.AddRange(productList);
context.SaveChanges();
//Dispose and create a context
context.Dispose();
context = new DbContext;
context.Configuration.AutoDetectChangesEnabled = false;
}
return context;
}
上面提到的代码段执行了一些其他任务,以提高性能,并且我们可以指定每个批处理中需要包含的记录数。 / p>
如果要插入批量记录,请为每个批次创建新的上下文 并在任务完成后处置。大大提高了性能 (从几分钟到操作到几秒钟)