代码之家  ›  专栏  ›  技术社区  ›  Red Riding Hood

如何使用ConstructUsing通过AutoMapper映射包裹的对象

  •  0
  • Red Riding Hood  · 技术社区  · 10 月前

    我正试图通过automapper将一个包装好的类打开包装到一个平面对象中。

    我研究了类似的问题,例如 AutoMapper c# runtime mapping depending on an object property ,但我希望派生类型由automapper映射,我不希望 return new MyFlatObject() 在我的automapper配置中

    所有属性都应通过 Value 子属性,仅限 IsDeleted 与家长相关。

    到目前为止我所拥有的:

    错误为:

    找到了未映射的成员。查看下面的类型和成员。添加自定义映射表达式、忽略、添加自定义解析程序,或 修改源/目标类型对于没有匹配的构造函数,添加 没有参数ctor,添加可选参数,或映射所有构造函数参数
    =>MyObject->MyFlatObject(目标成员列表)

    [TestClass]
    public class AutoMappingTest
    {
        public interface IMyObject { }
    
        public class DeletableWrapper
        {
            public bool IsDeleted { get; set; }
            public IMyObject Value { get; set; }
        }
    
        public class MyObject : IMyObject
        {
            public bool Foo { get; set; }
        }
    
        public class MyFlatObject
        {
            public bool IsDeleted { get; set; }
            public bool Foo { get; set; }
        }
    
        [TestMethod]
        public void MappingTest()
        {
     var config = new MapperConfiguration(cfg =>
     {
         cfg.CreateMap<DeletableWrapper, MyFlatObject>().ConstructUsing((src, ctx) => ctx.Mapper.Map<MyFlatObject>(src.Value))
         .ForMember(e => e.IsDeleted, opt => opt.MapFrom(s => s.IsDeleted));
    
         cfg.CreateMap<MyObject, MyFlatObject>();
     });
    
            config.AssertConfigurationIsValid();
        }
    }
    
    2 回复  |  直到 10 月前
        1
  •  2
  •   Yong Shun    10 月前

    注意:我的解决方案没有 ConstructUsing

    从…起 config.AssertConfigurationIsValid ,它抱怨没有成员的映射(规则) IsDeleted 在的(类)映射规则中 MyObject MyFlatObject .

    你可以申请 Ignore() 因为没有来自源的映射,因此它不会抱怨。

    对于压平,可以使用 IncludeMembers .

    var config = new MapperConfiguration((cfg) => 
    {
        cfg.CreateMap<AutoMappingTest.DeletableWrapper, AutoMappingTest.MyFlatObject>()
            .ForMember(dest => dest.IsDeleted, opt => opt.MapFrom(src => src.IsDeleted))
            .IncludeMembers(src => (AutoMappingTest.MyObject)src.Value);
    
        cfg.CreateMap<AutoMappingTest.MyObject, AutoMappingTest.MyFlatObject>()
            .ForMember(dest => dest.IsDeleted, opt => opt.Ignore());
    });
    
        2
  •  0
  •   Red Riding Hood    10 月前

    具有 ConvertUsing 这是可能的:

    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<DeletableWrapper, MyFlatObject>()
        .ConvertUsing((src, dst, ctx) =>
        {
            var result = ctx.Mapper.Map(src.Value, dst);
            result.IsDeleted = src.IsDeleted;
            return result;
        });
    
        cfg.CreateMap<MyObject, MyFlatObject>().ForMember(e => e.IsDeleted, opt => opt.Ignore());
    });
    

    然而,它不是很通用,每种类型都必须手动设置&忽略 IsDeleted 所有物