【问题标题】:Stored procedure whose result set lacks a primary key won't execute with Entity Framework 6结果集缺少主键的存储过程将无法使用 Entity Framework 6 执行
【发布时间】:2015-03-20 17:54:50
【问题描述】:

我正在调用一个存储过程,其结果集没有主键,也没有候选键。我创建了一个名为Foo 的实体来表示结果集中的一条记录,因此存储过程将生成List<Foo>。实体看起来像这样:

public class Foo {
    public Guid FooID { get; set; }
    public Guid AnotherFooID { get; set; }
    public string FooString { get; set; }
}

当我尝试按原样调用存储过程时,会导致编译错误,因为 Foo 没有定义主键。

我尝试在 EF 中为 Foo 定义一个主键,但是这个值永远不会从存储的过程中返回,所以我得到了这种错误:

数据读取器与指定的“Database.Foo”不兼容。类型的成员“FooPrimaryKey”在数据读取器中没有同名的对应列。

我无法修改存储过程以返回“唯一”列(这可能允许我创建实体并将该列定义为主键)。此外,Entity Framework 不允许我设置导入的函数to return a complex type,因为存储过程的返回语句中有if() 子句。

我不确定如何让 Entity Framework 帮助我执行存储过程并返回正确的结果。


编辑:我决定将实体中的每一列定义为一个大复合键。然后调用存储过程(像这样)返回正确的结果集:

var fooList = db.GetFoo(param1, param2); // etc.

但稍后,如果我再次查询数据库(在这种情况下,使用 LINQ),则会引发错误:

EntityFramework.SqlServer.dll 中出现“System.Data.Entity.Core.EntityCommandCompilationException”类型的异常,但未在用户代码中处理。准备命令定义时出错。

【问题讨论】:

  • 如何通过 EF 调用 SPROC?
  • @Amy 这是一个 Web API 2.0 项目,我在其中使用 Entity Framework 6。我尝试通过 using (var db = new FooEntities())List<Foo> foos = db.GetFoo(...) 调用存储过程
  • GetFoo是如何实现的?
  • @Amy GetFoo 是一个用 Transact-SQL 编写的存储过程。
  • 让我换个说法。 FooEntities.GetFoo 是如何实现的?转到 GetFoo 并在 Visual Studio 中按 F12。

标签: c# entity-framework stored-procedures entity-framework-6


【解决方案1】:

问题通过以下方式解决:

Foo 被定义为实体而非复杂类型。可能是因为Foo没有对应的数据库表,也没有办法创建。相反,我为Foo 添加了一个新的复杂类型。

接下来,我为后续的 LINQ 查询创建了第二个 using() 块。

最后,存储过程GetFoo() 能够被修改以返回单个可预测的结果集(第一个SP 返回两个完全不同的结果集之一,取决于if 语句的结果)。作为一些额外的预防措施,我确保每条结果记录都有一个唯一的 GUID 用作键(尽管我无法为其对应的复杂类型定义键),并且我为 SP 返回的每一列设置了别名。

我无法确切确定这些措施中的哪些解决了我的问题,但我希望这对遇到类似问题的人有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多