实体框架 4 函数导入不起作用

Posted

技术标签:

【中文标题】实体框架 4 函数导入不起作用【英文标题】:Entity Framework 4 Function Import not working 【发布时间】:2010-09-29 20:04:48 【问题描述】:

我正在使用带有 POCO 代码生成器的 Entity Framework 4。我有一个执行 INSERT 并返回插入记录的 @@IDENTITY 的存储过程。我正在尝试将存储过程作为一个函数导入到我的 .edmx 文件中,但是我在使用它时遇到了问题。

在模型浏览器中,我可以看到数据库层次结构下的存储过程,然后我右键单击并选择“Function Import...” 我尝试使用“None”作为返回类型以及Int32(即使它说“收集......”)。该函数出现在函数导入下,但即使在保存和编译之后,我也无法在我的 ObjectContext 中的任何地方找到该函数。我尝试删除它并重新导入存储过程几次,但均未成功。

注意:我有另一个执行直接 SELECT 的存储过程,它已正确导入并显示在 ObjectContext 代码中。

我是不是做错了什么?

【问题讨论】:

【参考方案1】:

如果您的存储过程不返回结果集,因此您在 Visual Studio 的“添加函数导入”对话框中选择“返回集合”“无”,则函数导入不会作为方法添加到您的生成的对象上下文。 (我还没有找到原因,但我仍在寻找。)

来自存储过程的返回值(例如,返回 @@identity)不是“返回集合”问题的含义。这就是为什么它不起作用。问题是询问从存储过程返回的结果集是什么。

我可以想到三种方法来处理您的问题:

    使用选择返回您的身份值(例如,选择 @@identity 作为身份),然后指定 Int32 的集合以回答“返回集合”问题。

    使用插入语句中的输出子句返回您的身份值,并以与 1 中相同的方式获取它。

    使用 Entity SQL 并将标识值作为输出参数。操作方法如下:How to: Execute a Query Using a Stored Procedure with In and Out Parameters

希望对你有帮助。

【讨论】:

【参考方案2】:

在调查 POCO .Context.tt 文件时,我在第 111 行附近发现了以下代码

if (edmFunction.ReturnParameter == null)

    continue;

string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));

这意味着任何返回 'none' 的函数导入都不会被写入。

我已经修改了我的.Context.tt 文件,以便将上面的代码替换为

string returnTypeElement = @"";
if (edmFunction.ReturnParameter == null)

    returnTypeElement = @"void";
 else 
    returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));

然后我不得不在函数声明周围添加一些检查(大约第 118 行)

<#
    if(returnTypeElement != "void")
#>
    <#=Accessibility.ForMethod(edmFunction)#> ObjectResult<<#=returnTypeElement#>>   <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#  
     else 
#>
    <#=Accessibility.ForMethod(edmFunction)#> <#=returnTypeElement#> <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#  
     
#>

和返回语句(大约第 142 行)

<#
    if(returnTypeElement != "void")
#>
        return base.ExecuteFunction<<#=returnTypeElement#>>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#  
     else 
#>
        base.ExecuteFunction("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#  
     
#>  

现在,这可能不是最优雅的解决方案(硬编码字符串!),但这确实意味着我可以在不返回任何内容并在 .Context.cs 中创建相应函数的存储过程上使用函数导入文件,因此可以通过 Intellisense 访问。

【讨论】:

以上是关于实体框架 4 函数导入不起作用的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码优先 - 初始代码迁移不起作用

具有接口的实体框架不起作用 - 处理相同的最佳方法是啥?

实体框架脚手架和迁移不起作用

C# - 实体框架代码优先,延迟加载不起作用

VS 2010 - 带有 MySql 存储过程的实体框架似乎不起作用

在实体框架 6 中不起作用的实体之间的一对一关系