EF Context具有意外的存储过程>功能映射

时间:2013-04-11 11:39:47

标签: entity-framework

当我将这样的sql存储过程导入我的数据库第一个模型

Declare@A int =0;
Declare@B int =0;
Declare@C int =0;

Set @A = (select Count ...)
Set @B = (select Count ...)
Set @C =  IsNull((@A + @B),0)
Select @C As UseCount

为什么EF会在生成的上下文中生成方法签名,返回类型为

ObjectResult<Nullable<int>>

而不仅仅是我期望的int的返回类型?

1 个答案:

答案 0 :(得分:1)

您必须“强力键入”返回集。一种方法是使用NOT NULL

列声明一个表变量
Set @A = (select Count(*) From Tasks)
Set @B = (select Count (*) From Tasks)
Set @C =  IsNull((@A + @B),0)
--Select @C As UseCount 
DECLARE @MyTableVar table(UseCount int NOT NULL)
INSERT @MyTableVar SELECT @C
SELECT TOP(1) UseCount FROM @MyTableVar

可以稍微缩短一点。

这将改变生成的方法

public virtual ObjectResult<Nullable<int>> TestProc()
{
    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<int>>("TestProc");
}

public virtual int TestProc()
{
    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("TestProc");
}

SORRY,CORRECTION - 虽然生成的方法看起来不错,但实际上并不起作用。第二个版本是从存储过程返回RETURN代码,而不是所需的标量结果。将表变量添加到存储过程中会对“实体框架添加功能导入”向导的“获取列信息”按钮产生影响 - Nullable列从true更改为false。但是,如果将返回类型设置为Scalars,则生成的方法仍使用Nullable&lt;&gt;。

您可以在DbContext的部分类中手动编写方法,如下所示:

public partial class OnModelCreatingEntities
{
    public virtual ObjectResult<int> TestProc2()
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<int>("TestProc");
    }
}

这会给出正确的结果,并且在重新生成类时不会覆盖。它也适用于原始的transact-sql。