我有一对简单的类,我在初始化时设置了一个映射.
public class Order {
public int ID { get; set; }
public string Foo { get; set; }
}
public class OrderDTO {
public int ID { get; set; }
public string Foo { get; set; }
}
...
Mapper.CreateMap<Order, OrderDTO>();
现在,在某一点上,我需要将订单映射到OrderDTO.但是根据某些情况,我可能需要在映射期间忽略Foo.我们还假设我无法在源或目标对象中“存储”条件.
我知道如何在初始化时配置被忽略的属性,但我不知道如何实现这样的动态运行时行为.
任何帮助,将不胜感激.
UPDATE
我对此行为的用例是这样的.我有一个ASP.NET MVC Web网格视图,它显示了OrderDTO列表.用户可以单独编辑单元格值.网格视图将编辑后的数据发送回服务器,就像OrderDTOs的集合一样,但是只设置了编辑的字段值,其他的则保留为默认值.它还发送有关为每个主键编辑哪些字段的数据.现在从这个特殊场景我需要将这些“半空”对象映射到Orders,但当然,跳过那些没有为每个对象编辑的属性.
另一种方法是进行手动映射,或以某种方式使用Reflection,但我只是考虑是否可以某种方式使用AutoMapper.
解决方法:
我已经深入研究了AutoMapper的源代码和示例,发现有一种方法可以在映射时传递运行时参数.
快速示例设置和用法如下所示.
public class Order {
public int ID { get; set; }
public string Foo { get; set; }
}
public class OrderDTO {
public int ID { get; set; }
public string Foo { get; set; }
}
...
Mapper.CreateMap<Order, OrderDTO>()
.ForMember(e => e.Foo, o => o.Condition((ResolutionContext c) => !c.Options.Items.ContainsKey("IWantToSkipFoo")));
...
var target = new Order();
target.ID = 2;
target.Foo = "This should not change";
var source = new OrderDTO();
source.ID = 10;
source.Foo = "This won't be mapped";
Mapper.Map(source, target, opts => { opts.Items["IWantToSkipFoo"] = true; });
Assert.AreEqual(target.ID, 10);
Assert.AreEqual(target.Foo, "This should not change");
事实上,这看起来非常“技术性”,但我仍然认为有很多用例,这真的很有帮助.如果根据应用程序的需要推广这个逻辑,并将其包含在一些扩展方法中,那么它可以更清晰.