12

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

使用代码优先方法和 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;
}

当我跟踪我的调试时,我的数据回来了,并且数据被映射到具有匹配名称的属性。但是,在输出中有一个名称中带有 a 的列"/"(例如: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]")]

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

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

但这会引发以下异常:

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

在我的项目NameSpace.Result中是一个类(为安全起见更改了名称),并且InfoDatais是我尝试使用 fluent-api 映射的属性(相应的 sql 列中包含 /;例如:Info/Data)。

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

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

4

3 回答 3

3

我现在意识到这是一个老问题,但是由于 OP 最近的回答已经提出了这个问题,也许人们仍然对此感兴趣。

如果您坚持按原样使用该存储过程并且它返回的列名与 EF 不兼容,看到您传入 SQL 以直接调用 proc SqlQuery,您是否可以使用 INSERT-EXEC 方法执行类似声明表变量(具有更兼容的列名),将存储的过程插入到表变量中,然后从表变量中选择作为结果集?

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

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

于 2014-06-12T11:49:46.780 回答
0

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

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

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

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

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

于 2012-04-15T02:39:30.770 回答
0

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

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

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

于 2014-06-05T17:35:25.537 回答