开发者

automapper - simplest option to only write to destination property if the source property is different?

开发者 https://www.devze.com 2023-02-13 03:00 出处:网络
NOTE: The scenario is using 2 entity framework models to sync data between 2 databases, but I\'d imag开发者_StackOverflowine this is applicable to other scenarios.One could try tackling this on the EF

NOTE: The scenario is using 2 entity framework models to sync data between 2 databases, but I'd imag开发者_StackOverflowine this is applicable to other scenarios. One could try tackling this on the EF side as well (like in this SO question) but I wanted to see if AutoMapper could handle it out-of-the-box

I'm trying to figure out if AutoMapper can (easily :) compare the source and dest values (when using it to sync to an existing object) and do the copy only if the values are different (based on Equals by default, potentially passing in a Func, like if I decided to do String.Equals with StringComparison.OrdinalIgnoreCase for some particular pair of values). At least for my scenario, I'm fine if it's restricted to just the TSource == TDest case (I'll be syncing over int's, string's, etc, so I don't think I'll need any type converters involved)

Looking through the samples and tests, the closest thing seems to be conditional mapping (src\UnitTests\ConditionalMapping.cs), and I would use the Condition overload that takes the Func (since the other overload isn't sufficient, as we need the dest information too). That certainly looks on the surface like it would work fine (I haven't actually used it yet), but I would end up with specifying this for every member (although I'm guessing I could define a small number of actions/methods and at least reuse them instead of having N different lambdas).

Is this the simplest available route (outside of changing AutoMapper) for getting a 'only copy if source and dest values are different' or is there another way I'm not seeing? If it is the simplest route, has this already been done before elsewhere? It certainly feels like I'm likely reinventing a wheel here. :)


Chuck Norris (formerly known as Omu? :) already answered this, but via comments, so just answering and accepting to repeat what he said.

@James Manning you would have to inherit ConventionInjection, override the Match method and write there return c.SourceProp.Name = c.TargetProp.Name && c.SourceProp.Value != c.TargetProp.Value and after use it target.InjectFrom(source);

In my particular case, since I had a couple of other needs for it anyway, I just customized the EF4 code generation to include the check for whether the new value is the same as the current value (for scalars) which takes care of the issue with doing a 'conditional' copy - now I can use Automapper or ValueInject or whatever as-is. :)

For anyone interested in the change, when you get the default *.tt file, the simplest way to make this change (at least that I could tell) was to find the 2 lines like:

if (ef.IsKey(primitiveProperty))

and change both to be something like:

if (ef.IsKey(primitiveProperty) || true) // we always want the setter to include checking for the target value already being set
0

精彩评论

暂无评论...
验证码 换一张
取 消