Как присвоить null для объекта, если члены объекта не имеют значения - automapper c# - PullRequest
1 голос
/ 03 апреля 2020

Я использую Autopper в 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 как ноль вместо типа объекта, если его члены не имеют значения. т.е.) DetailId и DetailName не имеют значения. Как это получить?

  "details" : null

Ответы [ 3 ]

3 голосов
/ 03 апреля 2020

Вы можете использовать условное отображение

    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();
      });
2 голосов
/ 03 апреля 2020

Вы можете сделать это с помощью AutoMapper после действия карты .

Примерно так:

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());
0 голосов
/ 03 апреля 2020

Вы можете использовать IValueResolver интерфейс для достижения того, что вам нужно. Документация: http://docs.automapper.org/en/stable/Custom-value-resolvers.html

Также есть похожий вопрос: Automapper, отображающий несколько свойств в одно свойство

Конфигурация:

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;
    }
}

Вы также можете опустить явную установку строк и классов в виде типов, допускающих значение NULL, с помощью ?, как здесь:

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

Поскольку тип string и любой класс null по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...