AutoMapper — проблема с IValueConverter в ReverseMap

Я пытаюсь сопоставить два класса ParentA и ParentB с помощью AutoMapper с настраиваемым преобразователем значений. Однако я столкнулся с проблемой при обратном сопоставлении с ParentB на ParentA.

Для сопоставления мы используем атрибуты AutoMapper.

Вот мой код:

ParentA ssssssss = new ParentA { Id = 1, isActive = "Y", Name = "test" };
var response = automapper.Map<ParentB>(ssssssss);
response.Value = 500;
var yyyy = automapper.Map<ParentA>(response);

Определения классов:

public class ParentA
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string isActive { get; set; }
}

[AutoMap(typeof(ParentA), ReverseMap = true)]
public class ParentB
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(IntConverter))]
    [SourceMember("isActive")]
    public int Value { get; set; } 
}

Конвертер:

public class IntConverter : IValueConverter<string, int>
{
    public int Convert(string sourceMember, ResolutionContext context)
    {
        if (sourceMember == "Y") return 100;
        if (sourceMember == "N") return 200;
        if (sourceMember == "P") return 500;
        return 1000;
    }
 
    public string Convert(int sourceMember, ResolutionContext context)
    {
        throw new NotImplementedException();
    }
}

Сопоставление от ParentA до ParentB работает правильно.

При обратном отображении из ParentB в ParentA происходит сбой, поскольку метод Convert для обратного отображения в IntConverter не реализован.

Не могли бы вы помочь мне реализовать обратное отображение в IValueConverter?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как насчет этого:

public class IntConverter : IValueConverter<string, int>
{
    public int Convert(string sourceMember, ResolutionContext context)
    {
        if (sourceMember == "Y") return 100;
        if (sourceMember == "N") return 200;
        if (sourceMember == "P") return 500;
        return 1000;
    }
 
    public string Convert(int sourceMember, ResolutionContext context)
    {
        if (sourceMember == 100) return "Y";
        if (sourceMember == 200) return "N";
        if (sourceMember == 500) return "P";
        return "your default";
    }
}

Но это кажется очевидным. У вас, должно быть, другая проблема?

Спасибо @decius, я пробовал, но не работает.

Jishnu Chandran 19.06.2024 08:17

Вы имеете в виду, что вы попробовали мой код, и он не работает, или вы вообще попробовали его сами?

decius 19.06.2024 08:25

Я сделал то же самое в IntConverter, но не реализовал код. Однако отладчик не использует этот метод.

Jishnu Chandran 19.06.2024 09:11
Ответ принят как подходящий

После некоторых проб и ошибок я пришел к выводу, что сопоставление на основе атрибутов имеет некоторые ограничения при выполнении обратного сопоставления с помощью преобразователя значений.

Реализация преобразователя значений поддерживает только одностороннее сопоставление.

Таким образом, я бы рекомендовал удалить ReverseMap = true из атрибута [AutoMap]. И вам следует применить атрибут [AutoMap] к классу ParentB, а атрибуты [SourceMember] и [ValueConverter] к свойству isActive.

[AutoMap(typeof(ParentB))]
public class ParentA
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(StringConverter))]
    [SourceMember("Value")]
    public string isActive { get; set; }
}

[AutoMap(typeof(ParentA))]
public class ParentB
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(IntConverter))]
    [SourceMember("isActive")]
    public int Value { get; set; }
}

public class StringConverter : IValueConverter<int, string>
{
    public string Convert(int sourceMember, ResolutionContext context)
    {
        
        if (sourceMember == 100)
            return "Y";
        if (sourceMember == 200)
            return "N";
        if (sourceMember == 500)
            return "P";
        return null;
    }
}

В противном случае вам следует работать с конфигурацией Fluent (Profile и/или MappingConfiguration), чтобы предоставить правило сопоставления для обратного сопоставления для свойства Value/isActive.

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<ParentA, ParentB>()
            .ForMember(dest => dest.Value, opt => opt.ConvertUsing(new IntConverter(), src => src.isActive))
            .ReverseMap()
            .ForMember(dest => dest.isActive, opt => opt.ConvertUsing(new StringConverter(), src => src.Value));
    }
}
Демо @ .NET Fiddle
Yong Shun 19.06.2024 09:27

Спасибо @Yong Shun, это сработало. Вы правы. Сопоставление на основе атрибутов имеет некоторые ограничения.

Jishnu Chandran 19.06.2024 13:09

Другие вопросы по теме