如果对象成员没有值,如何为对象分配 null - automapper c#

How to assign null for the object if object members have no value - automapper c#

我在 C# 中使用自动映射器。

class A 
{
   public int Value { get; set; }
   public string Code { get; set; }
   public B? Details { get; set; }
}

 class B 
 {
   public int Id { get; set;}
   public string Name { get; set; }
 } 

 class C
 {
   public int Value { get; set; }
   public string Code { get; set; }
   public int? DetailId { get; set; }
   public string? DetailName { get; set; }
 }

在自动映射器中,我使用如下:

CreateMap<C, A>()
.ForPath(o => o.Details.Id, b => b.MapFrom(z => z.DetailId))
.ForPath(o => o.Details.Name, b => b.MapFrom(z => z.DetailName))
.ReverseMap();

当我像上面的映射一样使用时,我得到的输出是

  "details ": {
        "id": 0,
        "name": ""
   }

如果它的成员没有值,我需要将 Details 值作为 null 而不是对象类型。即)DetailIdDetailName 没有价值。如何得到这个?

  "details" : null

您可以使用条件映射

    var config = new MapperConfiguration(cfg =>
      {
         cfg.CreateMap<C, B>()
            .ForMember(o => o.Id, b => b.MapFrom(z => z.DetailId))
            .ForMember(o => o.Name, b => b.MapFrom(z => z.DetailName));

          cfg.CreateMap<C, A>()
             .ForMember(o => o.Details, b => b.MapFrom((c, a, obj, context) => !string.IsNullOrEmpty(c.DetailName) ? context.Mapper.Map<B>(c) : null))
             .ReverseMap();
      });
    

您可以使用 AutoMapper after map action

像这样:

CreateMap<C, A>()
    .ForPath(o => o.Details.Id, b => b.MapFrom(z => z.DetailId))
    .ForPath(o => o.Details.Name, b => b.MapFrom(z => z.DetailName))
    .AfterMap((src, dest) =>
    {
        dest.Details = src.DetailId.HasValue && src.DetailName != null
            ? dest.Details
            : null;
    })
    .ReverseMap());

您可以使用IValueResolver界面来实现您所需要的。文档:http://docs.automapper.org/en/stable/Custom-value-resolvers.html

还有一个类似的问题:Automapper Mapping Multiple Properties to Single Property

配置:

CreateMap<C, A>()
.ForMember(o => o.Details, b => b.MapFrom<DetailsValueResolver>())
.ReverseMap();

实施:

// Note: this does not cover ReverseMap() when you would try to convert A to C
public class DetailsValueResolver : IValueResolver<C, A, B>
{
    // Runs every time you map C to A
    public B Resolve(C source, A destination, B destMember, ResolutionContext context)
    {
        // Covers cases where you can get null or empty DetailName, as well as null or zero DetailId
        if (!string.IsNullOrEmpty(source.DetailName) && source.DetailId > 0)
        {
            return new B { Id = (int)source.DetailId, Name = source.DetailName };
        }

        return null;
    }
}

您也可以像在此处所做的那样,使用 ? 省略显式设置字符串和 classes 作为可空类型:

public B? Details { get; set; }
public string? DetailName { get; set; }

因为 string 类型和任何 class 默认为 null