简体   繁体   中英

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.

I have a chunk of code that uses a database context and EF to call a stored procedure. 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.

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,

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?

Below I have provided two similar ways to handle messages returned by SQL Server. As noted in the comments, both involve the usage of the InfoMessage event on the connection.

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.

Solution 1: Catch Exception

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

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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