环境:
背景:存储过程在EDMX中。如果没有发生,我的存储过程将返回值设置为0,如果受影响则返回1,如果错误则设置@@ ERROR值。
背景1:我的存储过程LTM_Lease_DeleteSubFiles
在顶部执行SET NOCOUNT ON
,并在存储过程结束时使用RETURN
命令设置返回值
问题1:我的调用返回-1,即使在存储过程中也是如此:
var spResults = context.LTM_Lease_DeleteSubFiles(...)
背景2:我的存储过程DOIOwnerChanges_Apply
在存储过程结束时使用RETURN
命令设置返回值。
问题2 :我的调用返回值8,该值甚至在存储过程中找不到:
var spResults = context.DOIOwnerChanges_Apply(...)
答案 0 :(得分:0)
原因 - EF的模板构建器(包括v6)错误地将SP设置为返回包含行计数而不是返回值的INT,因为它错误地调用了错误的ObjectContext.ExecuteFunction(找到在模板生成的类YourDatabaseEntities中,它是DBContext的子级)。
为什么错误的ExecuteFunction? - 结果集错误地表示更改行的行数而不是返回值或输出参数,因为它调用了丢弃结果的不同ExecuteFunction。 ObjectContext.ExecuteFunction的flyover intellisense提示说"执行存储过程.... 丢弃从该函数返回的任何结果;并返回受执行影响的行数"而不是通常"执行存储过程....带有指定参数的 "。
为什么问题1为-1 :我认为SET NOCOUNT ON导致SP没有返回计数结果,并且Microsoft的ExecuteFunction将其作为错误代码返回。
为什么问题2为8 :SP返回8行数据而不是返回值,因为Microsoft使用了错误的ExecuteFunction。
SP修复问题1 - 您必须注释掉SET NOCOUNT ON。
SP修复问题1和2 - 您必须更改存储过程以将SELECT命令作为最后一个语句而不是RETURN命令。
SOLUTION FIX - 1)修复SP后,从Function Imports文件夹和Data Store的SP文件夹中删除SP。 [此更改导致EF模板生成器使SP调用成为可空INT的ObjectResult而不是单个INT结果。] 2)使用数据库中的"更新模型将SP重新加载到EDMX中。 3)重建EDMX所在的所有数据项目。 4)退出Visual Studio并返回。 5)重建整体解决方案。
其他解决方法 - 来源:Microsoft的David Browne - 1)重写SP,创建OUTPUT参数并在那里返回结果。 2)在发生错误时执行THROW或RAISERROR。