我需要在我的两个表中插入新行第一个表的自动生成的id字段是第二个表的字段之一。目前我使用事务来插入数据。我目前的代码如下:
using (var context = new ApplicationDatabaseEntities())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
foreach (var item in itemList)
{
context.MyFirstEntity.Add(item);
context.SaveChanges();
mySecondEntity.MyFirstEntityId = item.Id;
context.MySecondEntity.Add(mySecondEntity.MyFirstEntityId );
context.SaveChanges();
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine(ex);
}
}
}
上面的代码工作正常。我的问题是,这是正确的方法吗?我的意思是如果我有1000或2000个项目用于插入,我当前的代码会影响性能
答案 0 :(得分:4)
使用隐式事务可以改进代码:
foreach (var item in itemList)
{
context.MyFirstEntity.Add(item);
mySecondEntity.MyFirstEntity = item;
context.MySecondEntity.Add(mySecondEntity);
}
context.SaveChanges();
注意:我没有使用导航属性,而是使用导航属性。
答案 1 :(得分:1)
您应该将事务包装在using
语句中,并在抛出异常时回滚。
using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
try
{
foreach (var item in itemList)
{
context.MyFirstEntity.Add(item);
mySecondEntity.MyFirstEntity = item;
context.MySecondEntity.Add(mySecondEntity);
}
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
}
}
更多信息here。
答案 2 :(得分:1)
这取决于。如果整个批处理必须是事务性的,那么在一个大事务中你没有别的办法。如果必须保证交易只有交易,那么如果交易时间足够大,你可能会面临一些锁定。然后你可以在循环中为每个tupple做事务。
此外,您可以在没有明确交易的情况下一次完成您正在做的事情。您可以在循环后SaveChanges
进行交易:
foreach (var item in itemList)
{
context.MyFirstEntity.Add(item);
mySecondEntity.MyFirstEntity = item;
context.MySecondEntity.Add(mySecondEntity);
}
context.SaveChanges();