AutoMapper Project().To()和排序子集合

Iai*_*way 15 c# iqueryable automapper

我有一个对象图,我正在使用EF CodeFirst和AutoMapper从数据库加载到DTO中: -

public class Foo
{
  public int Id { get; set; }
  public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
  public int Id { get; set; }
  public int FooId { get; set; }
  public virtual Foo Foo { get; set; }

  public string Name { get; set; }
  public int SortOrder { get; set; }
}

public class FooDto
{
  public IEnumerable<BarDto> Bars { get; set; }
}

public class BarDto
{
  public string Name { get; set; }
  public int SortOrder { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的映射看起来像: -

mapper.CreateMap<Foo, FooDto>();
mapper.CreateMap<Bar, BarDto>();
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.我可以从我的上下文中获取实体并很好地投射到DTO: -

var foos = context.Foos.Project().To<FooDto>();
Run Code Online (Sandbox Code Playgroud)

然而,我不能用这种方法做的是将Bars它们SortOrder放在IQueryable里面.

如果我尝试: -

mapper.CreateMap<Foo, FooDto>()
  .ForMember(
    x => x.Bars
    opt => opt.MapFrom(src => src.Bars.OrderBy(x => x.SortOrder)));
mapper.CreateMap<Bar, BarDto>();
var foos = context.Foos.Project().To<FooDto>();
Run Code Online (Sandbox Code Playgroud)

我得到一个例外: -

System.InvalidOperationException: Sequence contains no elements
  at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
  at AutoMapper.MappingEngine.CreateMapExpression(Type typeIn, Type typeOut)
  ...
Run Code Online (Sandbox Code Playgroud)

似乎这与https://github.com/AutoMapper/AutoMapper/issues/159有关- 尽管我已经在使用复杂类型的子集合了.我猜CreateMapExpression不支持子集合上的OrderBy?

如果我没有使用.Project().To()那么我可以轻松地对子集合进行排序: -

var model = context.Foos.Select(x => new FooDto()
{
  Bars = x.Bars.OrderBy(y => y.SortOrder)
});
Run Code Online (Sandbox Code Playgroud)

但是我必须在任何我想要使用它的地方重复映射,否则使用AutoMapper的目的.

奇怪的是: -

1)我可以对子集合执行其他(更复杂的?)操作并将这些操作压平到我的父DTO中没问题: -

mapper.CreateMap<Foo, FooDto>()
  .ForMember(
    x => x.AllBarsHaveAName,
    opt => opt.MapFrom(src =>
      src.Bars.All(x => x.Name != null)));
Run Code Online (Sandbox Code Playgroud)

2)我可以Mapper.Map<FooDto>(foo);在记忆中就好了,它会对酒吧排序没问题.

可以在IQueryable级别对子集合进行排序,同时仍然使用.Project().To()?

Iai*_*way 13

完成修改AutoMapper源代码以支持此方案.希望提议的修复程序将被接受,但在此期间您可以在以下位置查看详细信息: -

https://github.com/AutoMapper/AutoMapper/pull/327