0

使用 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?");

        }
    }
}

我了解 IQueryable 扩展存在限制.Project().To<TDestination>但我不知道的是:

  • 哪个限制导致了这种行为?
  • 这是 Automapper 限制还是 LINQ 限制
  • 是否有解决办法仍然使用可查询的扩展而不是Mapper.Map<TDestination>(obj)专门恢复?

为后代:链接讨论主题

4

1 回答 1

1

这是 LINQ 限制。AutoMapper 不继承 LINQ 的基本映射。执行多态 Select 投影的 Select 表达式是什么?尝试这样做会导致您无法做到这一点。LINQ 查询提供程序不支持它。

于 2015-04-22T03:43:20.717 回答