实体框架(首先是数据库)存储过程的返回结果不正确

Eri*_*ood 7 c# sql-server stored-procedures entity-framework entity-framework-6

环境:

  • 视觉工作室 2017
  • SQL Server 2016
  • 采用数据库优先方法的 EF v6

背景:存储过程位于EDMX中。如果没有发生任何事情,我的存储过程将返回值设置为 0;如果有任何影响,则将返回值设置为 1;如果出现错误,则将返回值设置为 @@ERROR。

背景1:我的存储过程,在顶部LTM_Lease_DeleteSubFiles执行,并在存储过程末尾使用命令设置返回值。SET NOCOUNT ONRETURN

问题 1:我的调用返回 -1,它甚至不在存储过程中:

var spResults = context.LTM_Lease_DeleteSubFiles(...)
Run Code Online (Sandbox Code Playgroud)

背景2:我的存储过程在存储过程末尾DOIOwnerChanges_Apply用命令设置返回值。RETURN

问题 2:我的调用返回值 8,该值甚至在存储过程中都找不到:

var spResults = context.DOIOwnerChanges_Apply(...)
Run Code Online (Sandbox Code Playgroud)

Eri*_*ood 5

原因- EF(包括 v6)的模板构建器错误地将 SP 设置为返回包含行计数的 INT,而不是返回值,因为它错误地调用了错误的 ObjectContext.ExecuteFunction(在模板生成的类 YourDatabaseEntities 中找到,该类是DBContext 的子级)。

\n\n

为什么执行函数错误?- 结果集错误地显示了已更改行的行数,而不是返回值或输出参数,因为它调用了另一个丢弃结果的 ExecuteFunction。\nObjectContext.ExecuteFunction 的 Flyover 智能感知提示显示“执行存储过程 \xe2\ x80\xa6.;丢弃从函数返回的任何结果;并返回受执行影响的行数”,而不是通常的“使用指定参数执行存储过程 \xe2\x80\xa6. ”。

\n\n

为什么问题 1 是 -1:我相信 SET NOCOUNT ON 导致 SP 返回无计数结果,并且 Microsoft 的 ExecuteFunction 将其返回为错误代码。

\n\n

为什么问题 2 是 8:SP 返回 8 行数据而不是返回值,因为 Microsoft 使用了错误的 ExecuteFunction。

\n\n

SP 修复问题 1 - 您必须注释掉 SET NOCOUNT ON 。

\n\n

SP 修复问题 1 和 2 - 您必须更改存储过程以执行 SELECT 命令作为最后一条语句,而不是 RETURN 命令。

\n\n

解决方案修复- 1) 修复 SP 后,从 Function Imports 文件夹和 Data Store 的 SP 文件夹中删除 SP。[此更改导致 EF 模板生成器使 SP 调用成为可空 INT 的 ObjectResult,而不是单个 INT 结果。] 2) 使用“从数据库更新模型”将 SP 重新加载到 EDMX 3) 重建所有数据EDMX 所在的项目。4) 退出Visual Studio并返回。5)重建整体解决方案。

\n\n

其他解决方法-来源:Microsoft 的 David Browne - 1) 重写 SP,创建一个 OUTPUT 参数并在那里返回结果。2) 当发生错误时执行 THROW 或 RAISERROR。

\n