Я пытаюсь сопоставить два класса 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?





Как насчет этого:
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";
}
}
Но это кажется очевидным. У вас, должно быть, другая проблема?
Вы имеете в виду, что вы попробовали мой код, и он не работает, или вы вообще попробовали его сами?
Я сделал то же самое в IntConverter, но не реализовал код. Однако отладчик не использует этот метод.
После некоторых проб и ошибок я пришел к выводу, что сопоставление на основе атрибутов имеет некоторые ограничения при выполнении обратного сопоставления с помощью преобразователя значений.
Реализация преобразователя значений поддерживает только одностороннее сопоставление.
Таким образом, я бы рекомендовал удалить 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));
}
}
Спасибо @Yong Shun, это сработало. Вы правы. Сопоставление на основе атрибутов имеет некоторые ограничения.
Спасибо @decius, я пробовал, но не работает.