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

本文关键字:映射 结果 存储过程 框架 实体 | 更新日期: 2023-09-27 18:30:58

在过去的几天里,我一直在互联网上寻找与我的问题类似的主题。我终于求助于自己问这个问题。

使用代码优先方法和 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]")])。单步执行代码时,我看到分配了具有匹配列名的属性,但在分配期间忽略并跳过了具有列属性的属性。

我还为实体的每一列尝试了流畅的 api。

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

但这会引发以下异常:

数据读取器与指定的"命名空间.结果"不兼容。类型为"InfoData"的成员在数据读取器中没有具有相同名称的相应列。

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

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

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

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

我意识到这是一个古老的问题,但是由于OP最近的答案提高了它,也许仍然对它感兴趣。

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

这将是冗长的SQL传递,所以我不是一个可口的解决方案,但作为一个思考练习,看看这是否是解决问题的一种方式,我想我会提供它。

关于这类问题的好文章: http://www.sommarskog.se/share_data.html - 大多数方法都没有帮助,因为您无法更改存储的 proc(因此可能几乎无法访问数据库结构或根本不对其进行更改?),但是 INSERT-EXEC 方法作为一种可能的解决方法弹出,而无需更改数据库级别中的任何内容......

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

如何使用实体框架将存储过程的结果映射到具有不同命名参数的实体

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

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

从实体框架返回自定义对象<列表 T=">并分配给对象数据源

回过头来思考这个问题,最简单的(可能不是最干净或最好的解决方案)之一是将整个结果集包装在新过程中。 当然,如果您有能力在不破坏任何东西的情况下修改程序,那是您最好的解决方案。 但是,如果您无法修改输出,一种解决方案是使用 OPENROWSET(查看 Aaron 的答案)将过程输出抓取到表中,并使用新别名选择每列,该别名有效并遵守更干净的编程原则。

我希望这对将来的任何人都有帮助。

注意:
我尚未检查新版本的 EF 是否已解决此问题。