存储过程参数名称和实体框架

Posted

技术标签:

【中文标题】存储过程参数名称和实体框架【英文标题】:Stored procedure parameter names and Entity Framework 【发布时间】:2011-04-29 14:10:07 【问题描述】:

我已从 SQL Server 2005 数据库生成实体框架模型并开始导入存储过程。到目前为止一切顺利,但是当我尝试运行其中一个存储过程时会引发异常:

过程或函数“csp_getCoworker”需要参数“@@f​​irstname”,但未提供。

这是存储过程的签名:

ALTER PROCEDURE [dbo].[csp_getCoworker](
@@firstname nvarchar(32),
@@lastname nvarchar(32),
@@businessarea nvarchar(512),
@@location nvarchar(512)
)

这里是实体框架生成的代码

ObjectParameter p_firstnameParameter;
if (p_firstname != null)

    p_firstnameParameter = new ObjectParameter("p_firstname", p_firstname);

    else

     p_firstnameParameter = new ObjectParameter("p_firstname", typeof(global::System.String));

[...]
return base.ExecuteFunction<csp_getCoworker_Result2>("csp_getCoworker", p_firstnameParameter, p_lastnameParameter, p_businessareaParameter, p_locationParameter);

是不是参数名称中的双 @ 字符搞砸了?

【问题讨论】:

【参考方案1】:

我刚刚对此进行了测试,因为这是非常罕见的情况。

存储过程遵循非常奇怪的命名约定,因为不应使用@@。默认情况下,某些 SQL Server 系统变量使用它,不应将其用于其他任何东西。使用@x 作为存储过程的参数定义了一个参数x,但使用@@x 将定义参数@x - @ 是参数名称的一部分!

这在 C# 中是一个非常大的问题,因为 @ 是用于定义与保留关键字相同的变量名称的转义字符。例如:

string @string = "abc";

定义名为string 的变量。变量名不能以@开头。

实体框架通过将所有@ 替换为_ 并在SSDL 中直接在参数名称前加上p 来处理此问题。原因是从 SSDL 映射存储过程创建的函数导入必须具有与过程同名的参数,但同时不允许使用 @ 开头字符。如果您尝试手动修改 EDMX,它将无法通过自己的 XSD 验证,因为 @ 不允许作为 CSDL 中定义的标识符的起始字符。

即使这也可能被视为一个错误,它更多的是关于缺少更改 CSDL 中参数名称的可能性。目前这是设计使然,唯一的方法是更正 SQL 存储过程中的参数名称。

【讨论】:

这是一个很好的答案!它让我朝着正确的方向前进,我通过编写包装程序来解决这个问题,其中包含正确命名的变量,这些变量只是将它们传递给适当的 SP。 @Bartek:你应该做的是找到认为在参数名称中使用双@-标记是个好主意的人,打他们的脸,然后然后让他们修复它。 @Matti:我试过了,但他们早就离开了组织。 >:(

以上是关于存储过程参数名称和实体框架的主要内容,如果未能解决你的问题,请参考以下文章

实体框架存储过程表值参数

更新存储过程实体框架抛出“验证FunctionImport名称是唯一的”错误

使用实体框架从存储过程中获取数据时的参数问题

如何在 c# 实体框架核心中使用 FromSqlRaw() 将 OUTPUT 参数发送到 MySql 存储过程

使用实体框架获取存储过程输出参数抛出映射错误:数据读取器与指定的不兼容

以编程方式:列出在实体框架模型中找到的所有存储过程