Модели
public class NodeInfo
{
public double X { get; set; }
}
public class NetNode
{
public double X { get; set; }
}
Для моделей выше у меня есть следующая карта. Скажем, значение свойства «X» исходного объекта равно 5. Я ожидаю, что значение «o» будет равно 5, но оно всегда равно 0. Если я верну «s.X» вместо «o», он работает нормально, но я подумал, что TMember также должен был вернуть соответствующее значение свойства.
Профиль картографа
public class ProfileBase : Profile
{
public ProfileBase()
{
CreateMap<NodeInfo, NetNode>()
.ForMember(n => n.X, opt => opt.MapFrom((s, d, o, ctx) => o)).ReverseMap();
}
}
Я использую следующие перегрузки для сопоставления выше.
IMemberConfigurationExpression<TSource, TDestination, TMember>
MapFrom<TResult>(Func<TSource, TDestination, TMember, ResolutionContext, TResult> mappingFunction);
Исполнение
var config = new MapperConfiguration(cfg => {
cfg.AddProfile(new ProfileBase());
});
IMapper mapper = config.CreateMapper();
NodeInfo nodeInfo = new() { X = 5 };
NetNode netNode;
netNode = mapper.Map<NetNode>(nodeInfo);
//netNode.X should be 5 but it is 0
//change the "=> o" in the profile to "=> s.X" and it returns 5
Спасибо. В итоге я использовал ConvertUsing с элементом назначения, предоставленным в качестве параметра.





Этот TMember представляет целевой член целевого объекта, который является 0 значением свойства X вновь созданного экземпляра NetNode.
Из документации на GitHub:
Сопоставьте участника назначения с помощью пользовательской функции.
Доступ к источнику, целевому объекту, целевому члену и контекст.
/// <summary>
/// Map destination member using a custom function. Access the source, destination object, destination member, and context.
/// </summary>
/// <remarks>Not used for LINQ projection (ProjectTo)</remarks>
/// <param name = "mappingFunction">Function to map to destination member</param>
void MapFrom<TResult>(Func<TSource, TDestination, TMember, ResolutionContext, TResult> mappingFunction);
Спасибо. Я действительно не понимаю, почему у нас нет перегрузки для членов источника и членов назначения вместе. Мне нужно было использовать их обоих в ForAllMembers, у которого есть только <TSource, TDestination, object>. Поэтому мне пришлось добраться до места назначения через opt.DestinationMember, а затем добраться до элемента-источника с помощью ConvertUsing, указав элемент назначения в качестве параметра. Я думаю, это довольно сложно.
В общем случае член-источник отсутствует. У вас есть исходный элемент, когда вы его указываете, с преобразователем значений элементов или преобразователем значений. Преобразователь значения члена имеет доступ как к исходному, так и к целевому члену.
Я вижу, в моем конкретном случае мне нужно было преобразовать значение исходного элемента в определенный формат в зависимости от свойства типа целевого элемента. Поэтому я использовал PropertyInfo члена назначения, тип TSource и настраиваемое поле в дескрипторе настраиваемого свойства для метода преобразователя, который я использую для ConvertUsing.
Попробуйте docs.automapper.org/en/latest/Value-converters.html. У вас будет исходный член там.