简体   繁体   English

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

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

Whats the Perfered Method to handle Errors in a SQL Stored Procedure when Using Entity Framework.使用实体框架时处理 SQL 存储过程中的错误的首选方法是什么。

I have a chunk of code that uses a database context and EF to call a stored procedure.我有一段代码使用数据库上下文和 EF 来调用存储过程。 If everything is perfect, the stored procedure returns a list of keys to tell me which records were modified.如果一切正常,存储过程将返回一个键列表,告诉我哪些记录被修改。 If something goes wrong in the stored procedure, the transaction rolls back and I believe the response type is a string and causes this error:如果存储过程出现问题,事务将回滚,我认为响应类型是字符串并导致此错误:

The data reader has more than one field.数据读取器有多个字段。 Multiple fields are not valid for EDM primitive or enumeration types.多个字段对 EDM 原语或枚举类型无效。

After doing so digging I noticed that the SQL developer had put "PRINT: ERROR MESSAGE HERE" statement to pass back a message, However the current call does not allow for this,这样做挖掘后,我注意到 SQL 开发人员已将“PRINT:ERROR MESSAGE HERE”语句传回一条消息,但是当前调用不允许这样做,

Here is how the call is currently being made:以下是当前的调用方式:

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

The Current Code is expecting a list of Int and if a string is Returned it Errors out with the Error Message listed above, So what is the best way to handle errors coming back from a Stored Procedure in a Transaction Using Entity Framework 6?当前代码需要一个 Int 列表,如果返回一个字符串,它会出现上面列出的错误消息,那么处理从使用实体框架 6 的事务中的存储过程返回的错误的最佳方法是什么?

Below I have provided two similar ways to handle messages returned by SQL Server.下面我提供了两种类似的方法来处理 SQL Server 返回的消息。 As noted in the comments, both involve the usage of the InfoMessage event on the connection.如评论中所述,两者都涉及在连接上使用 InfoMessage 事件。

To answer your question, I don't really know of a preferred way to do handle PRINT statements as errors, but I am also not really sure of another way to handle the output.为了回答您的问题,我真的不知道将 PRINT 语句作为错误处理的首选方法,但我也不确定处理输出的另一种方法。

Solution 1: Catch Exception解决方案 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;
}

Solution 2: Check Field Count解决方案 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