实体框架存储过程结果映射

时间:2012-04-13 20:47:25

标签: c# .net entity-framework

过去几天,我在网上搜索了一个与我的问题类似的话题。我终于自己提出这个问题。

使用代码优先方法和EF 4.3.1我创建了一个上下文类,实体类和类来存储存储过程输出。上下文类具有使用SqlQuery<T>执行某些存储过程的方法。

示例:

public IEnumerable<Results> GetData(int id)
{
   var parameters = new SqlParameter[] { new SqlParameter("@id", id) };
   var result = this.Database.SqlQuery<Result>("Exec dbo.sproc_GetData @id",    parameters);
   var data= result.ToList<Result>();

   return data;
}

当我跟踪调试时,我的数据又回来了,数据被映射到具有匹配名称的属性。但是,在输出中有一个名称中包含"/"的列(例如:Info/Data)。显然我不能命名这样的属性所以我想我可以使用列属性([Column("Info/Data")])映射输出:

[Column("Info/Data")]
public string InfoData
{
   get { return infoData; }
   set { infoData= value; }
}

我甚至尝试使用逐字词运算符([Column(@"Info/Data")]),用[][Column("[Info/Data]")])包装文本,然后我尝试了两者([Column(@"[Info/Data]")])。单步执行代码时,我看到分配了具有匹配列名的属性,但是在分配期间会忽略具有column属性的属性并将其移除。

我还为该实体的每一栏尝试了fluent-api。

    modelBuilder.ComplexType<Result>().Property(d => d.InfoData).HasColumnName("Info/Data");

但会抛出以下异常:

  

数据阅读器与指定的'NameSpace.Result'不兼容。类型为“InfoData”的成员在数据读取器中没有相应的具有相同名称的列。

在我的项目中NameSpace.Result是一个类(为安全性而更改了名称),InfoDatais是我尝试使用fluent-api映射的属性(相应的sql列中有一个/; ex; :信息/数据)。

有没有人遇到过这个问题?

如果我的问题不明确或之前有人问过,请告诉我。

3 个答案:

答案 0 :(得分:3)

我现在意识到这是一个古老的问题,但是由于OP最近的回答已经提出了问题,或许它仍然有兴趣。

如果您按原样坚持使用存储过程,并且它返回的列名与EF不兼容,当您传入SQL以使用SqlQuery直接调用proc时,您是否可以使用INSERT- EXEC方法做一些事情,比如声明一个表变量(具有更多兼容的列名),INSERT-EXEC将存储过的proc放到表变量中,然后从表变量中选择作为结果集?

这是一个啰嗦的SQL传入,所以我不是一个可口的解决方案,但作为一个思考练习,看看这是否解决了这个问题,我认为我会提供它。

关于这类问题的好文章:http://www.sommarskog.se/share_data.html - 大多数方法没有用,因为你无法改变你的存储过程(因此可能几乎没有访问db结构或make完全改变了吗?),但是INSERT-EXEC方法作为一种可能的解决方法弹出而无需更改数据库级别中的任何内容......

答案 1 :(得分:0)

可能无法做你想做的事。使用Raw SQL时,绕过EF的映射部分。

How to use Entity Framework to map results of a stored procedure to entity with differently named parameters

与ExecuteStoreQuery相同 http://social.msdn.microsoft.com/Forums/pl/adonetefx/thread/d524b005-12a4-4300-a974-1e0582de876b

您可以使用ObjectQuery获取DbDataRecord对象的列表。然后使用Linq“选择”功能将结果映射到对象类型。如果将该映射包装在一个带有IEnumerable的扩展函数中并返回一个IEnumberable。

Return Custom Object <List T> from Entity framework and assign to Object Data Source

答案 2 :(得分:0)

回过头来思考这个问题,最简单的(可能不是最干净或最好的解决方案)之一就是将整个结果集包装在一个新程序中。当然,如果您能够修改程序而不破坏任何最佳解决方案。但是,如果您无法修改输出,则一个解决方案是使用OPENROWSET(查看Aaron的答案)将过程输出捕获到表中并选择具有新别名的每列,并且遵循更清晰的编程原则。

我希望这有助于将来的任何人。

注意:
我没有检查EF的新版本是否解决了这个问题。

相关问题