EF ef Database.SqlQuery 内部回滚到执行的存储过程

Posted

技术标签:

【中文标题】EF ef Database.SqlQuery 内部回滚到执行的存储过程【英文标题】:EF ef Database.SqlQuery internal rollback into executed stored procedure 【发布时间】:2014-09-01 13:32:24 【问题描述】:

我正在使用 EF 6 Database.SqlQuery 语句来执行存储过程,实现了错误和事务处理,打开和关闭事务(处理多条记录,如果一条记录出现错误,则回滚仅此,并提交其他任何内容完成没有错误)。

List<T> _result = this.Database.SqlQuery<T>(sqlStatement, parameters).ToList();

EF 使用自己的事务来执行 Database.SqlQuery,但是当发生错误时,我会回滚到存储过程中,此回滚也适用于 EF 事务。所以我得到了以下异常:

System.Data.SqlClient.SqlException (0x80131904):当前 事务无法提交并且无法支持以下操作 写入日志文件。回滚事务。

在这种情况下如何防止 EF 使用他自己的事务,或者防止程序关闭 EF 的事务?

【问题讨论】:

不要在您的存储过程中回滚。抛出异常,让客户端处理。 我不想更改 SP 错误处理,因为回滚它可能只针对其中一个已处理的记录。我希望提交没有错误的记录。 那你需要让EF不启动事务。如果存在外部事务,则所有行将全部为全部或全部为空。 更好的是,不要尝试插入无法通过约束验证的数据。您当然可以按照自己的意愿制作系统,但您在此处与最佳做法有些不符。 是的,这是我的问题,如果有某种方法可以防止 EF 为 SqlQuery 语句打开自己的事务。因为我没有自己的外部交易。当单独的事务进入存储过程是可以的,这意味着没有回滚但提交一切都在工作。提交不会关闭两个事务,但回滚会。回滚到程序会关闭我的事务,但也会关闭 EFs 事务。 【参考方案1】:

我发现在这种情况下,.SqlQuery 命令没有添加额外的事务,但错误是由执行过程到初始执行的存储过程产生的(有点复杂,但确实需要)。但是,我在使用 .ObjectContext.ExecuteStoreCommand 进行外部 EntityFramework 事务时遇到了这个问题,但我使用 TransactionalBehavior.DoNotEnsureTransaction 行为解决了这个问题。

例如:

        using (INotificationDataContext context = DataContextFactory.Create<INotificationDataContext>())
        
            result = (context as IObjectContextAdapter).ObjectContext.ExecuteStoreCommand(TransactionalBehavior.DoNotEnsureTransaction, sql, parameters);
        

【讨论】:

以上是关于EF ef Database.SqlQuery 内部回滚到执行的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

Ef执行Sql查询

EF中使用SQL语句或存储过程

EF中使用SQL语句或存储过程

EF框架使用sql语句或存储过程

必须使用 dbcontext.Database.SqlQuery 声明标量变量“@custid”?

EF 6 Plus - 如何进行未来的原始查询