简体   繁体   English

自动映射器投影不包括深度嵌套的层次对象

[英]Automapper projection doesn't include deeply nested hierarchical objects

I'm trying to use AutoMapper v6.1.1 to map a class using projection, but AutoMapper doesn't include deeply nested objects. 我正在尝试使用AutoMapper v6.1.1来使用投影映射类,但是AutoMapper不包含深层嵌套的对象。

I've attached a complete Visual Studio 2015 solution with a unit test here: https://www.dropbox.com/s/omue5ou5dvxsa57/UnitTestProject2.zip?dl=0 我在此处附加了完整的Visual Studio 2015解决方案和单元测试: https : //www.dropbox.com/s/omue5ou5dvxsa57/UnitTestProject2.zip?dl=0

I'm basically trying to map a Child and Parent hierarchy into a Person hierarchy, but the grand- Parents aren't getting included in the projection result. 基本上,我试图将映射ChildParent层次到Person的层次结构,但grand- Parents没有得到包含在投影的结果。

Models: 楷模:

public class Child
{
    public string Name { get; set; }

    public virtual Parent Parent { get; set; }
}

public class Parent
{
    public string Name { get; set; }

    public virtual Parent GrandParent { get; set; }
}

public class Person
{
    public string Name { get; set; }

    public virtual Person Parent { get; set; }
}

Mapping profile: 映射配置文件:

public class PersonProfile : Profile
{
    public PersonProfile()
    {
        this.CreateMap<Child, Person>()
            .MaxDepth(5);
        this.CreateMap<Parent, Person>()
            .ForMember(destinationMember => destinationMember.Parent, memberOptions => memberOptions.MapFrom(sourceMember => sourceMember.GrandParent))
            .MaxDepth(5);
    }
}

Unit test: 单元测试:

[TestClass]
public class UnitTest1
{
    IMapper mapper;
    List<Child> children;

    [TestInitialize]
    public void TestInitialize()
    {
        MapperConfiguration configuration = new MapperConfiguration((config =>
        {
            config.AddProfile(new PersonProfile());
            config.ForAllMaps((mapType, mapperExpression) =>
            {
                mapperExpression.MaxDepth(5);
            });
        }));

        this.mapper = configuration.CreateMapper();

        mapper.ConfigurationProvider.AssertConfigurationIsValid();

        this.children = new List<Child>
        {
            new Child
            {
                Name = "Child1",
                Parent = new Parent
                {
                    Name = "Parent1",
                    GrandParent = new Parent
                    {
                        Name = "GrandParent1",
                        GrandParent = new Parent
                        {
                            Name = "GreatGrandParent1"
                        }
                    }
                }
            }
        };
    }

    [TestMethod]
    public void TestProjection()
    {
        IQueryable<Person> people = children.AsQueryable().ProjectTo<Person>(mapper.ConfigurationProvider);

        AssertPeople(people);
    }

    [TestMethod]
    public void TestMap()
    {
        List<Person> people = mapper.Map<List<Child>, List<Person>>(children);

        AssertPeople(people.AsQueryable());
    }

    private void AssertPeople(IQueryable<Person> people)
    {
        Assert.IsNotNull(people);
        Assert.AreEqual(1, people.Count());

        Person child1 = people.ElementAt(0);
        Assert.AreEqual("Child1", child1.Name);

        Person parent1 = child1.Parent;
        Assert.IsNotNull(parent1);
        Assert.AreEqual("Parent1", parent1.Name);

        Person grandParent1 = parent1.Parent;
        Assert.IsNotNull(grandParent1); // fails when using ProjectTo
        Assert.AreEqual("GrandParent1", grandParent1.Name);
    }
}

Using the Map method works but ProjectTo doesn't. 使用Map方法有效,但ProjectTo无效。

The classes in the sample code are much simpler than those used in production. 示例代码中的类比生产中使用的类简单得多。

I'm trying to use projection so that I can return an IQueryable<Person> from OData and take advantage of the SQL generated by LINQ to Entities with query options automatically applied. 我试图用投影,这样我可以返回一个IQueryable<Person>从OData的,走的优势SQL所产生的LINQ to Entities自动应用的查询选项。

Any help is appreciated. 任何帮助表示赞赏。

Thank you! 谢谢!

I think this describes the issue: https://github.com/AutoMapper/AutoMapper/issues/2171 我认为这可以描述问题: https : //github.com/AutoMapper/AutoMapper/issues/2171

But as a workaround is it not possible to create an extension method that basically calls the Map internally: 但是,作为一种解决方法,不可能创建一个在内部基本上调用Map的扩展方法:

public static class Extenstions
{
    public static IQueryable<TDestination> ProjectToExt<TDestination, TSource>(this IQueryable<TSource> @this,
        IMapper mapper)
    {
        return mapper.Map<IEnumerable<TDestination>>(@this).AsQueryable();
    }
}

Then the calling code is like: 那么调用代码就像:

IQueryable<Person> people = children.AsQueryable().ProjectToExt<Person, Child>(mapper);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM