C# 实体框架“;无法提交当前事务,并且无法支持写入日志文件的操作。”;

C# 实体框架“;无法提交当前事务,并且无法支持写入日志文件的操作。”;,c#,sql,sql-server,entity-framework,transactions,C#,Sql,Sql Server,Entity Framework,Transactions,我正在开发的一个软件用于将CSV文件中的数据上传到数据库中。与数据库的交互使用EF6。要提交数据,有一个名为“InsertRow”的存储过程,它接受InterfaceID(字符串)、数据行(字符串)、分隔符字符(字符串),并具有输出参数:错误代码(int)和错误消息(0)。SP定义如下所示: CREATE PROCEDURE [dbo].[InsertRow] ( @InterfaceID NVARCHAR(MAX) , @Row NVARCHAR(MAX) , @Delimiter

我正在开发的一个软件用于将CSV文件中的数据上传到数据库中。与数据库的交互使用EF6。要提交数据,有一个名为“InsertRow”的存储过程,它接受InterfaceID(字符串)、数据行(字符串)、分隔符字符(字符串),并具有输出参数:错误代码(int)和错误消息(0)。SP定义如下所示:

CREATE PROCEDURE [dbo].[InsertRow]
(
  @InterfaceID NVARCHAR(MAX) ,
  @Row NVARCHAR(MAX) ,
  @Delimiter NVARCHAR(MAX) ,
  @ErrorCode INT OUTPUT ,
  @ErrorMessage NVARCHAR(MAX) OUTPUT    
)
它从如下实体中调用:

public virtual int InsertRow(string interfaceID, string row, string delimiter)
    {
        var errorCode = new ObjectParameter("ErrorCode", typeof(int));

        var errorMessage = new ObjectParameter("ErrorMessage", typeof(string));

        var interfaceIDParameter = interfaceID != null ?
            new ObjectParameter("InterfaceID", interfaceID) :
            new ObjectParameter("InterfaceID", typeof(string));

        var rowParameter = row != null ?
            new ObjectParameter("Row", row) :
            new ObjectParameter("Row", typeof(string));

        var delimiterParameter = delimiter != null ?
            new ObjectParameter("Delimiter", delimiter) :
            new ObjectParameter("Delimiter", typeof(string));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("InsertRow", interfaceIDParameter, rowParameter, delimiterParameter, errorCode, errorMessage);
    }
该过程仅在创建了临时表(在调用临时表之前完成)的情况下工作,因此在提交所有行时,EF上下文需要保持打开状态。这不是问题,正在处理中。该过程执行一些验证,显然还执行一些从字符串到正确数据类型的转换。输出参数Error Code和Error Message将填充应用程序要处理的错误信息。该过程以执行以下操作的catch结束:

    BEGIN CATCH 
    SET @ErrorCode = ERROR_NUMBER()  
    SET @ErrorMessage = ERROR_MESSAGE()
    INSERT INTO ErrorLog values (GetDate(),@InterfaceID, @Row, @Deliminator, ERROR_NUMBER(), ERROR_MESSAGE())
END CATCH;
大多数情况下,这是可行的。但是,在某些情况下,不会设置错误代码和错误消息,而是引发EntityCommandExecutionException,其中包含以下内部异常消息:

“无法提交当前事务,并且无法支持写入日志文件的操作。请回滚事务。”

我很难理解为什么一些抛出的错误会在这里被捕获并正确处理,而其他错误会失败。例如,当提交字符串“日期文本”作为应输入DateTime字段的行的一部分时。这应该被捕获并报告,但我得到的是一般异常

还值得注意的是,我也从Catch块中删除了insert语句。然后,异常的消息更改为

“在批处理结束时检测到不可提交的事务。事务将回滚。”


以前有人见过这个问题吗?我们在这里遗漏了什么可以帮助我们解决问题?什么会导致事务无法提交?我们需要有效地捕获这些消息,以便向用户报告其文件的问题。

有时事务确实是不可模仿的,例如,如果您试图插入一行,而目标表上有一个触发器,并且触发器失败

您应该始终检查
BEGIN CATCH
块中的
XACT_STATE()
,查看是否可以提交事务。有关更多信息,请参阅


如果您想可靠地记录故障,我建议使用SQL Audit功能,并在
BEGIN CATCH
块中使用
EXEC sp\u Audit\u write
过程。再次,请参阅以了解更多信息。或者有
RAISERROR。。。如果无法使用审核,则使用LOG
将消息记录到SQL Server错误日志。

实体框架引发此异常

这些都是罪魁祸首。我修改了一些模型,添加了迁移,更新了数据库。。。但不是触发因素

此异常是在处理过程中的某个点引发的

修复触发器解决了问题