繁体   English   中英

调用存储过程时使用实体框架处理响应时出错

[英]Error handling response with Entity Framework when calling stored procedure

使用实体框架时处理 SQL 存储过程中的错误的首选方法是什么。

我有一段代码使用数据库上下文和 EF 来调用存储过程。 如果一切正常,存储过程将返回一个键列表,告诉我哪些记录被修改。 如果存储过程出现问题,事务将回滚,我认为响应类型是字符串并导致此错误:

数据读取器有多个字段。 多个字段对 EDM 原语或枚举类型无效。

这样做挖掘后,我注意到 SQL 开发人员已将“PRINT:ERROR MESSAGE HERE”语句传回一条消息,但是当前调用不允许这样做,

以下是当前的调用方式:

var partIdsCreated = context.Database.SqlQuery<int>("EXEC My_SP @FilePath, @FileName", args).ToList();

当前代码需要一个 Int 列表,如果返回一个字符串,它会出现上面列出的错误消息,那么处理从使用实体框架 6 的事务中的存储过程返回的错误的最佳方法是什么?

下面我提供了两种类似的方法来处理 SQL Server 返回的消息。 如评论中所述,两者都涉及在连接上使用 InfoMessage 事件。

为了回答您的问题,我真的不知道将 PRINT 语句作为错误处理的首选方法,但我也不确定处理输出的另一种方法。

解决方案 1:捕获异常

public class DataLoader_01
{
    public int LoadData()
    {
        _infoMessage = null;
        using (var context = new ApplicationDbContext(@"Server=localhost\SQLEXPRESS;Database=StackOverflow;Trusted_Connection=True;"))
        {
            var sqlConnection = (SqlConnection)context.Database.Connection;
            sqlConnection.InfoMessage += InfoMessage;

            try
            {
                var t = context.Database.SqlQuery<int>("EXEC ErrorMessageHandling", new object[] {});
                return t.First();
            }
            catch (EntityCommandExecutionException e)
            {
                if (string.IsNullOrEmpty(_infoMessage))
                {
                    //do some error handling specific to your application
                    throw new ApplicationSpecificException(_infoMessage);
                }
                throw;
            }
        }
    }

    private void InfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        _infoMessage = e.Message;
    }

    private string _infoMessage;
}

解决方案 2:检查字段计数

public class DataLoader_02
{
    public int LoadData()
    {
        _infoMessage = null;

        using (var context = new ApplicationDbContext(@"Server=localhost\SQLEXPRESS;Database=StackOverflow;Trusted_Connection=True;"))
        {
            var sqlConnection = (SqlConnection)context.Database.Connection;
            sqlConnection.InfoMessage += InfoMessage;

            var cmd = context.Database.Connection.CreateCommand();
            cmd.CommandText = "[dbo].[SomeProc]";

            try
            {
                context.Database.Connection.Open();

                var reader = cmd.ExecuteReader();

                if (reader.FieldCount == 0)
                {
                    throw new ApplicationSpecificException(_infoMessage);
                }

                var result = ((IObjectContextAdapter)context).ObjectContext.Translate<int>(reader);

                return result.First();
            }
            finally
            {
                context.Database.Connection.Close();
            }
        }
    }

    private void InfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        _infoMessage = e.Message;
    }

    private string _infoMessage;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM