问题描述
使用Automapper 3.3.1.0与someEnumerable.AsQueryable().Project().To<TDestination>()
相比,在Mapper.Map<IEnumerable<TDestination>>(someEnumerable)
的用法之间存在不同的映射行为.
Using Automapper 3.3.1.0 there is a different mapping behavior between the usage of Mapper.Map<IEnumerable<TDestination>>(someEnumerable)
compared to someEnumerable.AsQueryable().Project().To<TDestination>()
这似乎不是SQL LINQ提供程序或其他限制,因为在内存中的集合中可以看到这一点.
This does not appear to be a limitation of a SQL LINQ provider or other as this is witnessed in an in-memory collection.
与很多事情一样,最好通过示例来解释:
As with many things this is best explained by example:
注意: 以下代码可在 https:/中找到/gist.github.com/kmoormann/b3949d006f4083ab6ee4
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using FluentAssertions;
using NUnit.Framework;
namespace Automapper.PolymorphicList.Tests
{
[TestFixture]
class AutomapperQueryableExtensionPolymorphism
{
//taking the class structure from: https://github.com/AutoMapper/AutoMapper/wiki/Mapping-inheritance
public class Order { }
public class OnlineOrder : Order
{
public string Referrer { get; set; }
}
public class MailOrder : Order { }
//Dtos
public class OrderDto
{
public string Referrer { get; set; }
}
[Test(Description = "Does the same mapping behavior exist for a polymorphic list when doing the project querable extension as when doing the static mapper map method()")]
public void IsSameBehaviorForQueryableExtensionAndStaticMap()
{
Mapper.Reset();
//Mappings
Mapper.CreateMap<Order, OrderDto>()
.Include<OnlineOrder, OrderDto>()
.Include<MailOrder, OrderDto>()
.ForMember(o => o.Referrer, m => m.Ignore());
Mapper.CreateMap<OnlineOrder, OrderDto>();
Mapper.CreateMap<MailOrder, OrderDto>();
//build lists
var onlineOrders = new List<OnlineOrder>() { new OnlineOrder() { Referrer = "one" }, new OnlineOrder() { Referrer = "two" } };
var mailOrders = new List<MailOrder>() { new MailOrder() };
//single typed list mapping
var mappedOnlineOrderDtos = Mapper.Map<IEnumerable<OrderDto>>(onlineOrders);
var projectedOnlineOrderDtos = onlineOrders.AsQueryable().Project().To<OrderDto>();
//using FluentAssertions for collection assertions
projectedOnlineOrderDtos.ShouldBeEquivalentTo(mappedOnlineOrderDtos, "automapper can handle singly typed lists");
//other single typed list mapping
var mappedMailOrderDtos = Mapper.Map<IEnumerable<OrderDto>>(mailOrders);
var projectedMailOrderDtos = mailOrders.AsQueryable().Project().To<OrderDto>();
projectedMailOrderDtos.ShouldBeEquivalentTo(mappedMailOrderDtos, "automapper can handle singly typed lists");
//build a polymorphic list
var orders = new List<Order>();
orders.AddRange(onlineOrders);
orders.AddRange(mailOrders);
// Perform Mapping and Projection
var mappedPolymorhpicOrders = Mapper.Map<IEnumerable<OrderDto>>(orders);
var projectedPolymorphicOrders = orders.AsQueryable().Project().To<OrderDto>();
projectedPolymorphicOrders.ShouldBeEquivalentTo(mappedPolymorhpicOrders, "automapper can handle polymorphic typed lists?");
}
}
}
我了解
限制 c2>可查询扩展,但我不知道的是:
I understand there are limitations to the .Project().To<TDestination>
IQueryable extensions but what I am unaware of is:
- 哪个限制导致此行为?
- 这是Automapper限制还是LINQ限制
- 是否有变通办法仍可以使用可查询的扩展名而不只恢复
Mapper.Map<TDestination>(obj)
?
- which limitation is causing this behavior?
- is this a Automapper limitation or a LINQ limitation
- is there a work around to still use the queryable extensions and not revert
Mapper.Map<TDestination>(obj)
exclusively?
后代: link 讨论主题
推荐答案
这是LINQ的限制. AutoMapper不会继承LINQ的基本映射.做多态Select投影的Select表达式是什么?尝试这样做会导致您无法做到这一点. LINQ查询提供程序不支持它.
This is a LINQ limitation. AutoMapper does not inherit base mappings for LINQ. What would be the Select expression to do polymorphic Select projections? Trying to do that leads you to where you can't do this. LINQ query providers don't support it.
这篇关于Automapper多态集合的IQueryable扩展行为不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!