Skip to main content
 首页 » 编程设计

c#之将多个源属性映射到单个目标属性

2024年06月20日12bjzhanghao

我想知道是否有办法使用一些自定义类型或值解析器来处理这种情况。

public class SuperDateTime 
{ 
    public DateTimeOffset Date { get; set; } 
 
    public string Timezone { get; set; } 
} 
 
public class Entity  
{ 
    public DateTimeOffset CreationDate { get; set; } 
 
    public string CreationDateZone { get; set; } 
 
    public DateTimeOffset EndDate { get; set; } 
 
    public string EndDateZone { get; set; } 
} 
 
public class Model 
{ 
    public SuperDateTime CreationDate { get; set; } 
 
    public SuperDateTime EndDate { get; set; } 
} 

当我在目标对象中有一个 SuperDateTime 时,我想用关联的 DateTimeOffset 和时区 string 实例化这个对象在源对象中。

当然我想做的是做一些通用的东西,所以不要去想每个 Entity 的每个 CreateMap 中的 MapFrom >

我尝试使用自定义 TypeConverter 来实现,但它仅支持 SourceType -> DestinationType 在我的例子中,我有一个 stringDateTimeOffset 必须创建一个 SuperDateTime

请您参考如下方法:

除了 LiamK 的建议之外,下一个可能的改进是编写一个辅助方法来执行 .MapFrom。根据您的要求,它可以简单也可以复杂。我将提供一个包含大量假设的简单模型,但您可以对其进行修改和优化以满足您可能的需求。

static IMappingExpression<TFrom, TTo> MapSuperDateTime<TFrom, TTo>( 
    this IMappingExpression<TFrom, TTo> expression,  
    Expression<Func<TTo, object>> dest) 
{ 
    var datePropertyName = ReflectionHelper.FindProperty(dest).Name; 
    var timezomePropertyName = datePropertyName + "Zone"; 
    var fromType = typeof (TFrom); 
    var datePropertyGetter = fromType.GetProperty(datePropertyName).ToMemberGetter(); 
    var timezonePropertGetter = fromType.GetProperty(timezomePropertyName).ToMemberGetter(); 
 
    return expression.ForMember(dest, opt => opt.MapFrom(src => new SuperDateTime 
    { 
        Date = (DateTimeOffset)datePropertyGetter.GetValue(src), 
        Timezone = (string)timezonePropertGetter.GetValue(src)          
    })); 
} 

然后你可以像这样指定你的映射:

Mapper.CreateMap<Entity, Model>() 
    .MapSuperDateTime(dest => dest.CreationDate) 
    .MapSuperDateTime(dest => dest.EndDate); 

假设是,如果你的实体 DateTimeOffset 被称为 bla,那么你对应的实体 string 被称为 blaZone,而你的模型 SuperDateTime 是称为 bla。