实体框架交易

时间:2014-07-20 19:00:43

标签: c# .net entity-framework

在Entity Framework 6中使用(重用)事务的最佳方法是什么。 使用案例: 如果我们有两种方法

public decimal Withdraw(string accNum, decimal amount) 
{
    using (var db = new MyDbContext())
    {
        var query = from t in db.MoneyTransactions
                    where t.AccountNumber.Equals(accNum)
                    select t;
        MoneyTransaction mt = query.First();
        mt.Amount -= amount;
        db.SaveChanges();
    }
    return amount;
}

public void Put(string accNum, decimal amount)
{
    using (var db = new MyDbContext())
    {
        var query = from t in db.MoneyTransactions
                    where t.AccountNumber.Equals(accNum)
                    select t;
        MoneyTransaction mt = query.First();
        mt.Amount += amount;
        db.SaveChanges();
     }
}

我想单独使用这些方法(例如,只是将钱存入帐户)并在单笔交易中使用它们:

public void Transfer(string srcAcc, string destAcc, decimal amount) 
{
    Withdraw(srcAcc,amount);
    Put(destAcc,amount);
}

2 个答案:

答案 0 :(得分:4)

查看Systems.Transactions程序集和命名空间。 (BCL的一部分)

然后你可以这样做:

using(var trans = new TransactionScope())
{
    Withdraw(srcAcc, amount);        // No changes needed to these
    Put(destAcc, amount);            //   two methods...

    trans.Complete();
}

System.Transactions将创建一个称为环境事务的事务。这是存储在线程上的事务,任何ADO.NET,LINQ-to-SQL和Entity Framework DB操作都将使用查找此TransactionScope对象。

此事务在using块结束时提交或回滚。 在TransactionScope对象上调用Complete()将触发数据库中的提交,而不调用Complete()将会回滚事务。

答案 1 :(得分:1)

您可以使用重载方法:

public void Put(string accNum, decimal amount, MyDbContext context)
{
    var query = from t in context.MoneyTransactions
                where t.AccountNumber.Equals(accNum)
                select t;
    MoneyTransaction mt = query.First();
    mt.Amount += amount;
    db.SaveChanges();
}

public void Put(string accNum, decimal amount)
{
    using (var db = new MyDbContext())
    {
        Put(accNum, amount, db);   
    }
}

Withdraw方法相同。然后你可以写:

using (var db = new MyDbContext())
using (var tran = db.Database.BeginTransaction())
{
    try
    {
        Withdraw(srcAcc, amount, db);
        Put(destAcc, amount, db);

        tran.Commit();
    }
    catch
    {
        tran.Rollback();

        throw;
    }
}

感谢重载方法,您不必重构其他现有方法来应用新参数(MyDbContext)。