【发布时间】:2013-01-30 06:06:35
【问题描述】:
我有一个使用 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; }
}
我的映射看起来像:-
mapper.CreateMap<Foo, FooDto>();
mapper.CreateMap<Bar, BarDto>();
到目前为止,一切都很好。我可以从我的上下文中抓取实体并很好地投射到 DTO:-
var foos = context.Foos.Project().To<FooDto>();
但是,我不能用这种方法对 Bars 进行排序,按 IQueryable 中的 SortOrder。
如果我尝试:-
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>();
我得到一个例外:-
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
at AutoMapper.MappingEngine.CreateMapExpression(Type typeIn, Type typeOut)
...
似乎这与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)
});
但是我必须在任何我想使用它的地方重复映射,这违背了使用 AutoMapper 的目的。
奇怪的是:-
1) 我可以对子集合执行其他(更复杂的?)操作并将它们展平到我的父 DTO 中没问题:-
mapper.CreateMap<Foo, FooDto>()
.ForMember(
x => x.AllBarsHaveAName,
opt => opt.MapFrom(src =>
src.Bars.All(x => x.Name != null)));
2)我可以Mapper.Map<FooDto>(foo);在内存中就好了,它会排序条没有问题。
是否可以在 IQueryable 级别对子集合进行排序,同时仍使用 .Project().To()?
【问题讨论】:
标签: c# automapper iqueryable