Automapper 多态集合的 IQueryable 扩展行为不同
IQueryable Extension Behavior Differing For Automapper Polymorphic Collection
使用 Automapper 3.3.1.0 在 Mapper.Map<IEnumerable<TDestination>>(someEnumerable)
与 someEnumerable.AsQueryable().Project().To<TDestination>()
的用法之间存在不同的映射行为
这似乎不是 SQL LINQ 提供程序或其他提供程序的限制,因为这是在内存集合中看到的。
与许多事情一样,这最好通过示例来解释:
注: 以下代码可在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?");
}
}
}
我知道 .Project().To<TDestination>
IQueryable 扩展有 limitations,但我不知道的是:
- 哪个限制导致了这种行为?
- 这是 Automapper 限制还是 LINQ 限制
- 是否有变通方法仍然使用可查询扩展而不是完全恢复
Mapper.Map<TDestination>(obj)
?
为了后代:link 讨论主题
这是 LINQ 限制。 AutoMapper 不继承 LINQ 的基本映射。进行多态 Select 投影的 Select 表达式是什么?尝试这样做会导致您无法做到这一点。 LINQ 查询提供程序不支持它。
使用 Automapper 3.3.1.0 在 Mapper.Map<IEnumerable<TDestination>>(someEnumerable)
与 someEnumerable.AsQueryable().Project().To<TDestination>()
这似乎不是 SQL LINQ 提供程序或其他提供程序的限制,因为这是在内存集合中看到的。
与许多事情一样,这最好通过示例来解释:
注: 以下代码可在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?");
}
}
}
我知道 .Project().To<TDestination>
IQueryable 扩展有 limitations,但我不知道的是:
- 哪个限制导致了这种行为?
- 这是 Automapper 限制还是 LINQ 限制
- 是否有变通方法仍然使用可查询扩展而不是完全恢复
Mapper.Map<TDestination>(obj)
?
为了后代:link 讨论主题
这是 LINQ 限制。 AutoMapper 不继承 LINQ 的基本映射。进行多态 Select 投影的 Select 表达式是什么?尝试这样做会导致您无法做到这一点。 LINQ 查询提供程序不支持它。