我正在调用一个存储过程,其结果集没有主键,也没有候选键。我创建了一个名为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'在数据读取器中没有相应的列具有相同的名称。
我无法修改存储过程以返回“唯一”列(这可能允许我创建实体并将此列定义为主键)。此外,实体框架不允许我设置导入的函数to return a complex type,因为存储过程的return语句中有if()
子句。
我不知道如何让Entity Framework帮助我执行存储过程并返回正确的结果。
编辑:我决定将实体中的每一列定义为一个大的复合键。然后调用存储过程(像这样)返回正确的结果集:
var fooList = db.GetFoo(param1, param2); // etc.
但是稍后,如果我再次查询数据库(在这种情况下,使用LINQ),则会抛出错误:
EntityFramework.SqlServer.dll中发生了'System.Data.Entity.Core.EntityCommandCompilationException'类型的异常,但未在用户代码中处理。准备命令定义时发生错误。
答案 0 :(得分:1)
问题以下列方式解决:
Foo
被定义为实体而非复杂类型。可能存在一个问题,即Foo
没有相应的数据库表,也无法创建一个。{1}}。相反,我为Foo
添加了一个新的复杂类型。
接下来,我为后续的LINQ查询创建了第二个using()
块。
最后,存储过程GetFoo()
能够被修改为返回单个可预测的结果集(第一个SP返回两个完全不同的结果集中的一个,取决于if
语句的结果)。作为一些额外的预防措施,我确保每个结果记录都有一个唯一的GUID用作键(尽管我无法为其相应的复杂类型定义键),并且我对SP返回的每一列都别名。
我无法确切地确定这些措施中的哪一项解决了我的问题,但我希望这对遇到类似问题的人有用。