如何基于运行时条件忽略属性? [英] How to ignore a property based on a runtime condition?

查看:86
本文介绍了如何基于运行时条件忽略属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一对简单的类,为它们在初始化时设置了一个映射.

I have a simple pair of classes which for I've set up a mapping at initialization time.

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

现在在某个时候我需要将Order映射到OrderDTO.但是根据某些情况,在映射过程中可能需要忽略Foo.我们还假设我无法将条件存储"在源对象或目标对象中.

Now at a certain point I need to map an Order to an OrderDTO. BUT depending on some circumstances, I might need to ignore Foo during mapping. Let's also assume that I cannot "store" the condition in the source or destination object.

我知道如何在初始化时配置被忽略的属性,但是我不知道如何实现这种动态的运行时行为.

I know how I can configure the ignored properties at initialization time, but I have no idea how I could achieve such a dynamic runtime behavior.

任何帮助将不胜感激.

更新

我对此行为的用例是这样的.我有一个ASP.NET MVC Web网格视图,该视图显示OrderDTO的列表.用户可以单独编辑单元格值.网格视图像OrderDTO的集合一样将已编辑的数据发送回服务器,但是仅设置了已编辑的字段值,其他字段保留为默认值.它还发送有关为每个主键编辑哪些字段的数据.现在,从这种特殊情况下,我需要将这些半空"对象映射到Order,但是,当然,跳过那些未为每个对象编辑的属性.

My use case for this behaviour is something like this. I have an ASP.NET MVC web grid view which displays a list of OrderDTOs. The users can edit the cell values individually. The grid view sends the edited data back to the server like a collection of OrderDTOs, BUT only the edited field values are set, the others are left as default. It also sends data about which fields are edited for each primary key. Now from this special scenario I need to map these "half-empty" objects to Orders, but of course, skip those properties which were not edited for each object.

另一种方法是进行手动映射,或者以某种方式使用Reflection,但是我只是在考虑是否可以以某种方式使用AutoMapper.

The other way would be to do the manual mapping, or use Reflection somehow, but I was just thinking about if I could use AutoMapper in some way.

推荐答案

我深入研究了AutoMapper的源代码和示例,发现有一种方法可以在映射时传递运行时参数.

I've digged into the AutoMapper source code and samples, and found that there is a way to pass runtime parameters at mapping time.

一个简单的示例设置和用法如下.

A quick example setup and usage looks like this.

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

实际上,这看起来很技术性",但是我仍然认为有很多用例确实有用.如果将此逻辑根据应用程序的需要进行概括,并包装到某些扩展方法中,则可能会更加简洁.

In fact this looks quite "technical", but I still think there are quite many use cases when this is really helpful. If this logic is generalized according to application needs, and wrapped into some extension methods for example, then it could be much cleaner.

这篇关于如何基于运行时条件忽略属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆