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

本文关键字:实体 框架 参数 存储过程 | 更新日期: 2023-09-27 17:53:38

我已经从SQL Server 2005数据库生成了一个实体框架模型,并开始导入存储过程。到目前为止一切正常,但是当我试图运行其中一个存储过程时,它抛出了一个异常:

过程或函数' csp_getcolleague '期望参数'@@firstname',该参数未提供。

下面是存储过程的签名:

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

是参数名中的两个@字符搞砸了事情吗?

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

我只是测试了这个,因为它是非常罕见的场景。

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

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

string @string = "abc";

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

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

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