c# - 使用 BeginTransaction() 的 Entity Framework

标签 c# entity-framework

我正在尝试在我的应用程序中实现 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/

相关文章:

c# - 如何在 JavaScript 中使用 C# 枚举值

c# - ServiceBase.Run(ServiceBase[] ) 方法是否异步运行数组中的所有服务?

c# - 计算 2 个日期时间之间的差异(Timespan + double)

c# - 哪里返回错误记录

c# - 通过 Entity Framework 将相关记录插入数据库

mysql - 将 TEXT 字段添加到 MySql 的 Entity Framework 模型

c# - Visual Studio - 默认转到接口(interface)的实现

c# - 为什么对象 ref1 在 Console.WriteLine (ref1) 之后准备好进行 GC?

c# - LINQ 中 select 中的 cast 和 as 之间的区别

c# - 使 Firebird 与 Entity Framework Code First 和迁移一起工作