我正在将我的EF linq查询更改为存储过程.是否有简单的方法来设置复杂的映射

本文关键字:简单 是否 方法 映射 复杂 设置 存储过程 我的 EF linq 查询 | 更新日期: 2023-09-27 17:54:27

我有一个包含5个独立表的实体框架项目。当我从这些表中查询数据并使用.Include()时,它生成的查询非常慢并且超时。

我已经将查询移动到存储过程,现在我正在寻找一种方法来查询这个存储过程,并轻松地将它返回的数据映射到现有的数据类。

我对EF的DataContext的原始Linq查询是这样的:

var data = (from a in context.A
                    .Include("B")
                    .Include("C")
                    .Include("D")
                    .Include("E")
            where a.Id == someValue
            select a);

它返回一个类似于下面的Entity数据对象:

class A
{
    int Id;
    string otherProperties;
    List<B> B;
    List<C> C;
    List<D> D;
    List<E> E;
}

EF生成的在SQL server上运行的查询返回的结果集看起来像这样:

<>之前C1 c2 c3 c4 c5 c6 c7 c8 c9 c10----------------------------------------------------------A1 a2 b1 b2A1 a2 c1 c2A1 a2 c1 c2A1 a2 c1 c2A1 a2 d1 d2A1 a2 d1 d2A1 a2 d1 d2A1 a2 e1 e2A1 a2 e1 e2之前

(假设1条B记录,3条C记录,3条D记录,2条E记录。

我在存储过程中复制了这个查询,并将其运行时减少到几乎没有,但是我一直在试图找出如何将结果集映射到我的实体框架数据类(上面的类A)。

EF绝对有能力做到这一点,因为当我使用Linq查询时,它已经在幕后的某个地方完成了,但我不确定这是否是我可以访问的东西。

是否有一个简单的方法在实体框架映射一个单一的存储过程(函数导入)到一个多层次的实体框架类?

我正在将我的EF linq查询更改为存储过程.是否有简单的方法来设置复杂的映射

我发现了一篇博客文章,解释了如何使用实体框架实现这一点。

http://blogs.infosupport.com/ado-net-entity-framework-advanced-scenarios-working-with-stored-procedures-that-return-multiple-resultsets/

简单地说,你需要编写你的存储过程,使它以实体框架所期望的特定方式返回你的数据,然后你可以使用一些EF扩展来定制你的存储过程执行,并实现你的对象图。

看起来这是内置到实体框架在未来的版本(5.0+我相信),但是这个解决方案看起来应该工作在较低的版本。

虽然在我的情况下,我发现,如果我只是摆脱了.Include()在我的Linq查询和手动触发加载其他属性通过引用他们在返回对象之前的代码,我的性能问题得到了修复。这是因为它不是在5个未优化连接的表之间构建一个庞大的查询,而是运行5个单独的查询,每个查询只提取它需要的特定数据。

当我通过将昂贵的查询转换为存储过程来优化EntityFramework时,我为结果创建了一个自定义类,然后在DbContext中执行一些逻辑将我的自定义类转换为实体。

所以你可以创建一个像

这样的东西
public class StoreProcARow
{
public string Name {get;set;} // properties for every column
}

然后在DbContext

public A GetA(int ID)
{
// do stored procedure
IEnumerable<StoreProcARow> procResult = ...
// process procResult into A type
}

试试AutoMapper。

你可以这样做:

using AutoMapper;
...
Mapper.CreateMap<DataModel.B, ReplyObjects.B>;
Mapper.CreateMap<DataModel.C, ReplyObjects.C>;
...
return new A
{
  B = Mapper.Map<DataModel.B, ReplyObjects.B>(varContainingDataForB),
  C = Mapper.Map<DataModel.C, ReplyObjects.C>(varContainingDataForC)
  ...
};

只要你的ReplyObjects中的属性。B匹配数据模型的名称和类型。B,一切都会自动映射出来!

相关文章: