【发布时间】:2019-02-21 10:15:00
【问题描述】:
更新:
Automapper 在简单的情况下会自动应用它,因为它already adds a ToList()。我看到的导致我提出这个问题的问题原来是一个更复杂的问题(SoftwareIds member 是N+1 的罪魁祸首。请参阅this。)。
在 EF Core 2.1 中,我们支持在 LINQ 子查询中添加 ToList() 以缓冲结果并避免 N+1 数据库查询。 (Docs) 这对于针对 DbContext 的普通 LINQ 查询非常有效。
但是,如果我的 Automapper 配置文件会导致 N+1 个查询:
public MyMappingProfile() =>
CreateMap<MyEntity, MyDto>().ForMember(e => e.MyCollectionProp, o => o.MapFrom(l => l.MyCollectionPropMany.Select(la => la.MyCollectionEntity)))
添加ToList()会抛出异常:
public MyMappingProfile() =>
CreateMap<MyEntity, MyDto>().ForMember(e => e.MyCollectionProp, o => o.MapFrom(l => l.MyCollectionPropMany.Select(la => la.MyCollectionEntity).ToList()))
System.NotSupportedException: '无法解析表达式 'MyDto.MyCollectionPropMany.Select(la => la.MyCollectionEntity).ToList()':这个方法的重载 'System.Linq.Enumerable.ToList' 当前不受支持。'
有没有办法在 Automapper 配置文件中启用子查询缓冲?
型号:
public class MyEntity
{
public int Id { get; set; }
public ICollection<MyCollectionPropMany> MyCollectionPropManys { get; set; }
...
}
public class MyCollectionPropMany
{
public int MyEntityId { get; set; }
public MyEntity MyEntity { get; set; }
public int MyCollectionPropId { get; set; }
public MyCollectionProp MyCollectionProp { get; set; }
}
public class MyCollectionProp
{
public int Id { get; set; }
public ICollection<MyCollectionPropMany> MyCollectionPropManys { get; set; }
...
}
public class MyDto
{
public int Id { get; set; }
public IEnumerable<MyCollectionPropDto> MyCollectionPropDtos { get; set; }
...
}
public class MyCollectionPropDto
{
public string Name { get; set; }
...
}
Automapper v7.0.1
真实场景(我试图简化/使 SO 通用):Source 在这个真实示例中,Languages 和 Tags 成员通过多对多当前正在生成 N+1 查询。
【问题讨论】:
-
能否提供样例实体和dto模型。还有 AutoMapper 版本。
-
因为 AutoMapper automatically includes ToList 为你服务。
-
嗨@IvanStoev,我用模型和 AutoMapper 版本更新了问题。根据您的第二条评论,如果 AutoMapper 自动添加子查询上的
ToList()缓冲,您知道为什么我的映射配置文件可能会创建 N+1 个查询吗? -
我先看看能不能复制。
-
谢谢。我还刚刚在最底部添加了一个指向我要优化的实际映射配置文件的链接。
标签: c# linq entity-framework-core automapper