【问题标题】:how to set Automapper ignore null?如何设置 Automapper 忽略 null?
【发布时间】:2019-03-14 19:22:41
【问题描述】:

我目前在我的 .net core (2.1) api 项目中使用 Automapper (8.0.0)。下面是我的代码示例,用于模拟我的 dto 映射到我的数据库对象的更新过程。我希望自动映射器忽略 Dto 中空对象的映射。

using AutoMapper;
using System;

namespace testAutoMapper
{
public class SourceObject
{
    public bool TestReverseFalse { get; set; }
    public bool TestReverseTrue { get; set; }
    public bool IFalse { get; set; }
    public bool ITrue { get; set; }
    public int TestInteger { get; set; }
    public int TestNullInteger { get; set; }
}

public class ModelObject
{
    public bool? TestReverseFalse { get; set; }
    public bool? TestReverseTrue { get; set; }
    public bool? IFalse { get; set; }
    public bool? ITrue { get; set; }
    public int? TestInteger { get; set; }
    public int? TestNullInteger { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        AutoMapper.Mapper.Initialize(mapper =>
        {
            //global ignore for all
            //mapper.ForAllMaps((tm, me) => me.ForAllMembers(option => option.Condition((src, destination, sourceMember) => sourceMember != null)));

            mapper.CreateMap<ModelObject, SourceObject>().ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
        });

        var model = new ModelObject
        {
            TestReverseFalse = true,
            TestReverseTrue = false,

        };
        var source = new SourceObject
        {
            TestReverseFalse = false,
            TestReverseTrue = true,
            ITrue = true,
            IFalse = false,
            TestInteger = 100,
            TestNullInteger = 100
        };

        Console.WriteLine("Source Before Mapping");
        Console.WriteLine("TestReverseFalse: " + source.TestReverseFalse);
        Console.WriteLine("TestReverseTrue: " + source.TestReverseTrue);
        Console.WriteLine("ITrue:" + source.ITrue);
        Console.WriteLine("IFalse:" + source.IFalse);
        Console.WriteLine("TestInteger:" + source.TestInteger);
        Console.WriteLine("TestNullInteger:" + source.TestNullInteger);


        Mapper.Map(model, source);

        Console.WriteLine();
        Console.WriteLine("After Mapping");
        Console.WriteLine("TestReverseFalse: " + source.TestReverseFalse);
        Console.WriteLine("TestReverseTrue: " + source.TestReverseTrue);
        Console.WriteLine("ITrue:" + source.ITrue);
        Console.WriteLine("IFalse:" + source.IFalse);
        Console.WriteLine("TestInteger:" + source.TestInteger);
        Console.WriteLine("TestNullInteger:" + source.TestNullInteger);
        Console.ReadLine();
    }
}

}

样本输出


Source Before Mapping
TestReverseFalse: False
TestReverseTrue: True
ITrue:True
IFalse:False
TestInteger:100
TestNullInteger:100

After Mapping
TestReverseFalse: True
TestReverseTrue: False
ITrue:False
IFalse:False
TestInteger:0
TestNullInteger:0

我发现我的源对象被重置为其默认值。 不知道我做错了哪一部分。

【问题讨论】:

标签: .net-core automapper


【解决方案1】:

使用 null 检查的自定义解析器来解决此问题。 用这个替换你的初始化:

初始化:

Mapper.Initialize(mapper =>
{
    mapper.ForAllPropertyMaps(pm => true /*Whether to use this resolver. This returning true means it's always used*/, (pm, c) => c.MapFrom<NonNullOnlyResolver, object>(pm.SourceMember.Name));

    mapper.CreateMap<ModelObject, SourceObject>();
});

解析器:

class NonNullOnlyResolver : IMemberValueResolver<object, object, object, object>
{
    public object Resolve(object source, object destination, object sourceMember, object destMember, ResolutionContext context)
    {
        return sourceMember ?? destMember;
    }
}

更改后的输出:

Source Before Mapping
TestReverseFalse: False
TestReverseTrue: True
ITrue:True
IFalse:False
TestInteger:100
TestNullInteger:100

After Mapping
TestReverseFalse: True
TestReverseTrue: False
ITrue:True
IFalse:False
TestInteger:100
TestNullInteger:100

【讨论】:

  • 当源类型不具有目标类型的所有属性时,始终使用此解析器 (pm =&gt; true) 会破坏一些复杂的映射,甚至是简单的映射。我最终只将它应用于可为空的类型,例如 @tchuat 发布的 in this issue
猜你喜欢
  • 1970-01-01
  • 2021-05-16
  • 2011-01-27
  • 2019-01-02
  • 1970-01-01
  • 2017-12-29
  • 1970-01-01
  • 2017-12-31
  • 2010-10-31
相关资源
最近更新 更多