实体框架 - DbContextTransaction.Rollback() 中的问题

2024-02-02

我使用连接数据库Entity Framework。我实现了一个联系人存储库来保存联系信息(示例存储库)。在上述类文件中,我声明了一个static property用于处理DBEntities (i.e., BLabsEntities)即“Context”并且还宣布了static property for DbContextTransaction.

在下面的代码中,我添加了一个 try catch 块来处理 Entity Framework 中的异常SaveContact()存储库方法。我发起了一个transaction在上述方法中开始保存联系人过程之前,我将异常数据添加到数据库表中dbo.Contact根据我的想法,它抛出了exception。在 Catch 块中我正在启动Rollback上述交易的过程,我正在尝试将异常消息插入到ErrorLog Table,但即使执行了回滚过程,Context 属性仍保留联系人信息。因此,在尝试将记录插入到中时,它再次在 catch 块中抛出异常dbo.ErrorLog Table。我添加了调试快照供您参考。

C# Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace EF_Sample
{
    public class ContactRepository
    {
        private static BLabsEntities _context;
        private static DbContextTransaction _dbTransaction;

        protected static BLabsEntities Context
        {
            get { return _context ?? (_context = new BLabsEntities()); }
        }

        protected static DbContextTransaction DBTransaction
        {
            get { return _dbTransaction; }
            set { _dbTransaction = value; }
        }

        public void SaveContact(Contact contact = null)
        {
            try
            {
                if (contact == null)
                {
                    contact = new Contact()
                    {
                        FirstName = null,
                        LastName = null
                    };
                }


                BeginTransaction();
                Context.Contacts.Add(contact);
                Context.SaveChanges();
            }
            catch (Exception ex)
            {
                CommitTransaction(false);

                BeginTransaction();
                ErrorLog error = new ErrorLog()
                {
                    Message = ex.Message
                };

                Context.ErrorLogs.Add(error);

                Context.SaveChanges();
            }
            finally
            {
                CommitTransaction();
            }
        }

        private void BeginTransaction()
        {
            DBTransaction = Context.Database.BeginTransaction();
        }

        private void CommitTransaction(bool flag = true)
        {
            try
            {
                if (flag)
                {
                    DBTransaction.Commit();
                }
                else
                {
                    DBTransaction.Rollback();
                }
            }
            catch (Exception Ex)
            {
                Console.WriteLine("Error: {0}", Ex.Message);
            }
        }
    }
}

调试快照:

异常于try Block:通过代码显式创建异常

异常于Catch Block:失败Rollback手术

数据库表结构:

请帮助我如何做Rollback操作成功到清除上下文更改.


实际的答案可能更简单:

https://github.com/aspnet/EntityFramework.Docs/issues/327 https://github.com/aspnet/EntityFramework.Docs/issues/327

在大多数情况下,对 dbContextTransaction.Rollback() 的显式调用是不必要的,因为在 using 块末尾处理事务将负责回滚。

如果 SQL Server 中发生足够严重的错误, 事务将自动回滚,并且调用 catch 块中的 dbContextTransaction.Rollback() 实际上会失败。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 - DbContextTransaction.Rollback() 中的问题 的相关文章

  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 为什么我的 CASE 语句要求 THEN 部分的数据类型为 INT?

    我正在尝试运行一个查询 其中以下 CASE 语句是其中一行 我正在使用报表生成器 3 0 但是 我收到一条错误消息 将 varchar 值 Case 1 转换为 int 数据类型时转换失败 Microsoft SQL Server 错误 2
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • SQL Server 2014 安装中缺少 SQL Server Integration Services

    我正在尝试使用 Integration Services 安装 SQL Server 2014 Here https www microsoft com en US download details aspx id 42299是我以前用工具
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 可以获取SQL Server中当前执行的存储过程的行号吗?

    几年前 我在 Sybase Delphi 环境中工作 使用 BDE 连接到数据库服务器 我们有一个 Delphi 小应用程序 给定当前正在执行的存储过程的名称 它可以告诉您当前正在执行该存储过程的哪一行 这对于调试似乎挂起的存储过程非常有用
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何获得顶部带有千位分隔符的数字?

    SELECT count FROM table A 假设结果是8689 我怎样才能将它转换为8 689在 SQL Server 上 尝试这样 select replace convert varchar convert Money coun
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何跨多个表强制执行 CHECK 约束

    我有一个在 Microsoft SQL Server 2012 Express 中记录奶牛繁殖信息的数据库 显然 一头牛只有在出生后才能配种 并且在其一生中可能会配种多次 我需要在我的数据库中强制执行这些约束 我目前已经根据下图安排了一个架
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 如何修改现有表以添加时区

    我有一个包含 500 多个表的大型应用程序 我必须将应用程序转换为时区感知 当前应用程序使用new java util Date GETDATE 与服务器的时区 即没有任何时区支持 我已将这项任务分为几个步骤 以便于开发 我确定的第一个步骤

随机推荐