实体框架 - Database.ExecuteSqlCommand - 执行sql transaction命令

时间:2015-11-16 04:42:38

标签: entity-framework entity-framework-6

我试图通过Database.ExecuteSqlCommand()执行SQL事务命令,但在尝试提交事务时收到错误:

  

底层提供程序在提交时失败   System.Exception {System.Data.Entity.Core.EntityException}

     

值不能为空。\ r \ n参数名称:连接
  System.Data.Entity.Core.EntityClient.EntityTransaction.Commit()
  在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction [T](Func`1 func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
  ... System.Data.Entity.Database.ExecuteSqlCommand(String sql,Object [] parameters)   ......

internal partial class MyEntities
{
    public string BeginTrx(int levelIndex)
    {
        if (TrxList == null) TrxList = new Dictionary<int, MyTransactionScope>();

        var trxNm = GenRandomTrxNm();
        TrxList[levelIndex] = new MyTransactionScope(this, levelIndex, trxNm);

        var sql = string.Format("BEGIN TRAN {0}", trxNm);
        Database.ExecuteSqlCommand(sql);

        return trxNm;
    }

    public Dictionary<int, MyTransactionScope> TrxList { get; protected set; }

    string GenRandomTrxNm()
    {
        var sb = new StringBuilder(Guid.NewGuid().ToString());
        sb.Replace("-", "");
        sb.Insert(0, "T");

        if (sb.Length > 32) sb.Length = 32;

        return sb.ToString();
    }

    public void RollbackTrx(int levelIndex)
    {
        var trxScope = TrxList[levelIndex];

        var sql = string.Format("ROLLBACK TRAN {0}", trxScope.TransactionName);
        Database.ExecuteSqlCommand(sql);

        var newEntries = ChangeTracker.Entries().Where(x => (x.State != EntityState.Unchanged) && !trxScope.EntityEntries.Contains(x));

        foreach(var entry in newEntries)
        {
            entry.State = EntityState.Unchanged;
        }

        TrxList.Remove(levelIndex);
    }

    public void CommitTrx(int levelIndex)
    {
        var trxScope = TrxList[levelIndex];

        var sql = string.Format("COMMIT TRAN {0}", trxScope.TransactionName);
        Database.ExecuteSqlCommand(sql, Database.Connection);

        TrxList.Remove(levelIndex);
    }
}

public class MyTransactionScope
{
    public int Level { get; set; }
    public string TransactionName { get; set; }
    public List<DbEntityEntry> EntityEntries { get; set; }

    public MyTransactionScope(DbContext dbCntx, int level, string transactionName)
    {
        Level = level;
        TransactionName = transactionName;

        EntityEntries = dbCntx.ChangeTracker.Entries().ToList();
    }
}

0 个答案:

没有答案