存储过程参数名称和实体框架
我已经从 SQL Server 2005 数据库生成了一个实体框架模型,并开始导入存储过程。到目前为止一切顺利,但是当我尝试运行其中一个存储过程时,它会引发异常:
过程或函数“csp_getCoworker”需要参数“@@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);
是否是参数名称中的双 @ 字符弄乱了事情?
I've generated an Entity Framework model from an SQL Server 2005 database and started to import stored procedures. So far so good, but one of the stored procedures throws an exception when I try to run it:
Procedure or function 'csp_getCoworker' expects parameter '@@firstname', which was not supplied.
Here is the signature for the stored procedure:
ALTER PROCEDURE [dbo].[csp_getCoworker](
@@firstname nvarchar(32),
@@lastname nvarchar(32),
@@businessarea nvarchar(512),
@@location nvarchar(512)
)
And here is the code generated by Entity Framework
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);
Is it the double @-characters in the parameter name that's messing things up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我刚刚对此进行了测试,因为这是非常罕见的情况。
存储过程遵循非常奇怪的命名约定,因为不应使用@@。默认情况下,某些 SQL Server 系统变量会使用它,并且不应将其用于其他任何用途。使用
@x
作为存储过程的参数定义了参数x
,但使用@@x
将定义参数@x
- @ 是参数名称的一部分!这在 C# 中是一个非常大的问题,因为 @ 是转义字符,用于定义与保留关键字相同的变量名称。例如:
定义名为
string
的变量。变量名不能以@开头。实体框架通过直接在 SSDL 中将所有
@
替换为_
并在参数名称前加上p
前缀来处理此问题。原因是从SSDL映射存储过程创建的函数导入必须具有与过程同名的参数,但同时不允许使用@作为起始字符。如果您尝试手动修改 EDMX,它自己的 XSD 验证将会失败,因为 CSDL 中定义的标识符不允许使用 @ 作为起始字符。即使这也可能被视为一个错误,但更多的是缺少更改 CSDL 中参数名称的可能性。目前这是设计使然,唯一的方法是更正 SQL 存储过程中的参数名称。
I just tested this because it is very uncommon scenario.
The stored procedure follows very strange naming convention because @@ should not be used. It is by default used by some SQL server system variables and should not be used for anything else. Using
@x
as parameter of stored procedure defines a parameterx
but using@@x
will define parameter@x
- @ is part of parameter name!This is a very big problem in C# because @ is escape character used to define names of variables same as reserved keywords. For example:
defines variable named
string
. Variable name cannot start with @.Entity framework deals with this by replacing all
@
with_
and prefixing parameter's name withp
directly in SSDL. The reason is that function imports created from SSDL mapped stored procedure must have parameters with the same name as the procedure but in the same time @ is not allowed starting character. If you try to modify EDMX manually it will fail its own XSD validation because @ is not allowed starting character for identifiers defined in CSDL.Even this can probably be considered as a bug it is more about missing possibility to change the name of the parameter in CSDL. At the moment this is by design and only way is to correct names of parameters in SQL stored procedure.