2017-07-21 131 views
1

我想使用AutoMapper v6.1.1来映射一个类使用投影,但AutoMapper不包括深层嵌套的对象。Automapper投影不包括深层嵌套的分层对象

我附加一个完整的Visual Studio 2015年解决方案可以与单元测试在这里: https://www.dropbox.com/s/omue5ou5dvxsa57/UnitTestProject2.zip?dl=0

基本上,我想一个ChildParent层次映射到Person层次,但grand- Parents麦凯纳不包括在投影结果中。

型号:

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; } 
} 

映射分布:

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); 
    } 
} 

单元测试:

[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); 
    } 
} 

使用Map方法的作品,但ProjectTo没有。

示例代码中的类比生产中使用的类简单得多。

我在尝试使用投影,以便我可以从OData中返回IQueryable<Person>,并利用LINQ to Entities生成的SQL,并自动应用查询选项。

任何帮助表示赞赏。

谢谢!

+0

我不认为这是AM问题。目前没有办法定义和翻译递归表达式(与递归lambda委托相反)。 –

回答

0

我认为这说明了问题: https://github.com/AutoMapper/AutoMapper/issues/2171

但作为一种解决方法是不是可以创建基本内部调用地图的扩展方法:

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

然后调用代码是这样:

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