我正在尝试在我的应用程序中实现 Entity Framework ,我应该能够手动提交和回滚更改。
当我第一次执行更新语句时,它成功地更新了表并且我能够回滚更改。 这是正确的
但是当我第二次执行更新语句时,它成功更新了表并提交了更改。所以我无法手动回滚。 这是错误的
请告诉我发生这种情况的原因以及如何解决此问题。
下面的代码只是重现我的问题的示例。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data;
namespace EFTest
{
public class DBOperations
{
NorthwindEntities NorthwindContext;
DbTransaction transObject;
public DBOperations()
{
}
public void ConnectDB()
{
try
{
if (NorthwindContext == null)
{
NorthwindContext = new NorthwindEntities();
if (NorthwindContext != null && NorthwindContext.Connection.State != ConnectionState.Open)
{
NorthwindContext.Connection.Open();
transObject = NorthwindContext.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
}
}
}
catch (Exception ex)
{
throw new Exception("Database Error " + ex.Message);
}
}
public int disconnect()
{
if (NorthwindContext != null && transObject != null)
{
try
{
transObject.Rollback();
}
catch (Exception)
{
}
transObject.Dispose();
NorthwindContext.Connection.Close();
NorthwindContext.Dispose();
}
return 0;
}
public void CommitTransaction()
{
if (NorthwindContext != null && transObject != null)
{
try
{
transObject.Commit();
}
catch (Exception)
{
}
}
}
public void RollbackTransaction()
{
if (NorthwindContext != null && transObject != null)
{
try
{
transObject.Rollback();
}
catch (Exception)
{
}
}
}
public int UpdateDB()
{
int _returnVal = 0;
try
{
NorthwindContext.ExecuteStoreCommand("UPDATE Orders SET OrderDate = GETDATE() WHERE OrderID = '10248'");
}
catch (Exception ex)
{
throw new Exception("Database Error " + ex.Message);
}
return _returnVal;
}
}
public class program
{
public program()
{
//Establishing the connection.
DBOperations _DBOperations = new DBOperations();
_DBOperations.ConnectDB();
//Update the datebase
_DBOperations.UpdateDB(); //Update the database but it doesn't commit the changes.
//Issue Rollback to rollback the transaction.
_DBOperations.RollbackTransaction(); //Successfully Rollbacks the database changes.
//Again Update the datebase
_DBOperations.UpdateDB(); //Update the database it commits the changes.
//Issue Rollback to rollback the transaction.
_DBOperations.RollbackTransaction(); //Rollback fails.
}
}
}
最佳答案
与 TransactionScope
您的 DbOperations 可能如下所示:
public class DBOperations : IDisposable
{
NorthwindEntities _context;
private TransactionScope _transactionScope;
public DBOperations()
{
this.Initialize();
}
private void Initialize()
{
try
{
this.Dispose();
this._transactionScope = new TransactionScope();
this._context = new NorthwindEntities();
// no need to open connection. Let EF manage that.
}
catch (Exception ex)
{
throw new Exception("Database Error " + ex.Message);
}
}
public void RollbackTransaction()
{
try
{
this._transactionScope.Dispose();
this._transactionScope = null;
this.Dispose();
this.Initialize();
}
catch (Exception)
{
// TODO
}
}
public int UpdateDB()
{
int _returnVal = 0;
try
{
this._context.ExecuteStoreCommand("UPDATE Orders SET OrderDate = GETDATE() WHERE OrderID = '10248'");
}
catch (Exception ex)
{
throw new Exception("Database Error " + ex.Message);
}
return _returnVal;
}
public void Dispose()
{
if (this._transactionScope != null)
{
this._transactionScope.Complete();
this._transactionScope.Dispose();
}
if (this._context != null) this._context.Dispose();
}
}
和程序:
public class program
{
public program()
{
using (DBOperations dbOperations = new DBOperations())
{
dbOperations.UpdateDB(); // Update the database no commit.
dbOperations.RollbackTransaction(); // Rollback.
dbOperations.UpdateDB(); // Update the database no commit.
dbOperations.RollbackTransaction(); // Rollback.
} // Commit on Dispose.
}
}
在 TransactionScope 范围内打开的连接会自动登记在事务中。事务仅通过调用Complete()
提交。处置或未处理的异常将导致回滚。
如果您做的不仅仅是存储命令,如更改对象和依赖上下文的更改跟踪,您可以实现重试机制,而不是仅仅丢弃上下文和更改。
关于c# - 使用 BeginTransaction() 的 Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12544441/