1

我有两张桌子。第一个表包含一些数据。第二个表包含数据更改的历史记录。第一个表还包含引用最后一个历史行的列。当第一个表中的行中的数据发生更改时,副本被插入到第二个表中,并在引用最后一个数据副本的第一列中更新。为此,我使用此代码

using (TransactionScope trn = new TransactionScope())
{
  Table1 t1=model.Table1.Where(t=>t==id).FirstOrDefault();
  /*update Table1 data*/
  Table2 t2=new Table2();
  t2.Table1=t1;
  model.AddToTable2(t2);
  /*set Table2 fields*/
  model.SaveChanges();

  t1.ref=t2.id;
  model.SaveChanges();
  trn.Complete();
}

使用 TransactionScope 保存符合数据是正确的吗?或者我需要使用其他方法?

4

2 回答 2

1

您需要保存更改两次吗?如果表格是相关的,您应该能够设置导航属性并只保存一次所有更改。在这种情况下,您不需要自己创建交易 - EF 会为您创建一个。如果您需要保存更改两次 TransactionScope 应该可以解决问题。连接在打开时被登记到事务中。在代码片段中,您没有显示上下文是如何实例化的,以及连接在到达事务之前会发生什么,因此很难判断它是否正确。

于 2012-11-21T05:56:43.857 回答
-1

Context 类默认支持事务。但是对于上下文类的每个新实例,都会创建一个新事务。这个新事务是一个嵌套事务,一旦关联上下文类上的 SaveChanges() 被调用,它将被提交。

在这种情况下,我们甚至不需要 TransactionScope。我们可以简单地检查两个操作的结果,如果它们成功,我们只需要调用 SaveChanges() 方法。

当我们将 ADO.NET 调用与实体框架混合时,通常需要 TransactionScope。在这种情况下使用 TransactionScope 的技巧是让上下文类知道您想将它与您自己的事务一起使用。由于事务与作用域中的连接对象相关联,因此我们需要将上下文类与与事务作用域相关联的连接一起使用。此外,我们需要让上下文类知道它不能拥有连接,因为它由调用代码拥有。所以我们可以做类似的事情:

using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
{ 
    using (var conn = new SqlConnection("...")) 
    { 
        conn.Open(); 

        var sqlCommand = new SqlCommand(); 
        sqlCommand.Connection = conn; 
        sqlCommand.CommandText = 
            @"UPDATE Blogs SET Rating = 5" + 
                " WHERE Name LIKE '%Entity Framework%'"; 
        sqlCommand.ExecuteNonQuery(); 

        using (var context = 
            new BloggingContext(conn, contextOwnsConnection: false)) 
        { 
            var query = context.Posts.Where(p => p.Blog.Rating > 5); 
            foreach (var post in query) 
            { 
                post.Title += "[Cool Blog]"; 
            } 
            context.SaveChanges(); 
        } 
    } 

    scope.Complete(); 
} 

请参阅:http: //msdn.microsoft.com/en-us/data/dn456843.aspx

于 2014-12-09T05:57:23.373 回答