使用实体框架时,所提供的方法是如何处理SQL存储过程中的错误。
我有一大堆代码使用数据库上下文和EF来调用存储过程。如果一切都很完美,存储过程将返回一个键列表,告诉我哪些记录被修改。如果存储过程中出现问题,事务将回退,我相信响应类型是一个字符串并导致此错误:
数据阅读器有多个字段。多个字段对EDM原语或枚举类型无效。
在进行了挖掘后,我注意到SQL开发人员已将“PRINT:ERROR MESSAGE HERE”语句传回消息,但当前调用不允许这样做,
以下是目前正在进行的通话方式:
var partIdsCreated = context.Database.SqlQuery<int>("EXEC My_SP @FilePath, @FileName", args).ToList();
当前代码期望一个Int列表,如果返回一个字符串,则错误输出上面列出的错误消息,那么使用Entity Framework 6处理从事务中的存储过程返回的错误的最佳方法是什么? ?
答案 0 :(得分:1)
下面我提供了两种类似的方法来处理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;
}