我试图通过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();
}
}