AutoMapper:展平时如何使用字符串参数映射

AutoMapper: How to MapFrom with string parameter when flattening

AutoMapper 的 MapFrom 方法有两个重载:

.MapFrom(Expression<Func<object, object>>

.MapFrom<TMember>(string)

第一个重载可以这样使用:

.ForMember(dest => dest.Date, opt => opt.MapFrom(order => order.Customer.DateOfBirth))

我试过这样的第二次重载:

.ForMember(dest => dest.Date, opt => opt.MapFrom<DateTime>("Order.Customer.DateOfBirth"))

但是在使用关联的属性时它不起作用。谁知道在使用扁平化时如何使用第二个重载?

我问这个是因为我正在寻找一种动态映射的方法;例如:

.ForMember(dest => dest.Date, opt => opt.MapFrom<DateTime>(givenPropertyString))

提前致谢。

似乎 MapFrom 重载 .MapFrom<TMember>(string) 不能很好地处理嵌套属性(我在这里可能是错的)。但是,对于您的问题,您可以创建一个自定义方法来使用反射获取嵌套的子 属性 值。并使用它来动态映射任何 属性 值 string NestedPropertyName.

这是自定义方法(方法来源here

public static object GetNestedPropertyValue(object obj, string nestedDottedPropertyName)
{
    foreach (String part in nestedDottedPropertyName.Split('.'))
    {
        if (obj == null)
            return null;

        PropertyInfo info = obj.GetType().GetProperty(part);
        if (info == null)
            return null;

        obj = info.GetValue(obj, null);
    }
    return obj;
}

并且您可以在 MapFrom 中动态地使用此方法(对于任何 属性),就像这样

.ForMember(dest => dest.Date, 
            opt => opt.MapFrom(src => GetNestedPropertyValue(src, "Order.Customer.DateOfBirth")));

有几个选项可以使用 Automapper 动态映射类型。

首先,如果在编译时源类型未知,Automapper DynamicMap 应该被使用。它只允许指定目标类型:

var message = Mapper.DynamicMap<ICreateOrderMessage>(order);

关于您关于 MapFrom(string) 的问题 - it works 您建议的精确度:

Mapper.CreateMap<UserModel, UserDto>()
    .ForMember(dto => dto.FullName, opt => opt.MapFrom<string>("FirstName"));

可能像您的 "Order.Customer.DateOfBirth" 这样的嵌套属性不受支持。