实体框架6交易

时间:2015-06-25 08:16:15

标签: c# entity-framework-6

我需要在我的两个表中插入新行第一个表的自动生成的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个项目用于插入,我当前的代码会影响性能

3 个答案:

答案 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();