【问题标题】:Nullable datetime to datetime converter automapper可空日期时间到日期时间转换器自动映射器
【发布时间】:2013-05-03 11:44:08
【问题描述】:

我的 DTO 需要 DateTime 属性,但我的 POCO 使用可为空的日期时间。为了避免必须为具有此条件的每个属性创建ForMember 映射,我创建了一个ITypeConverter<DateTime?, DateTime>。我遇到的问题是当 DTO 和 POCO 都具有可以为空的 DateTimes 时调用此转换器。 DestinationTypeDateTime,即使该属性是可为空的日期时间。知道如何使该转换器仅在实际可为空的日期时间运行吗?

public class FooDTO
{
    public DateTime? FooDate { get; set; }
}

public class FooPoco
{
    public DateTime? FooDate { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Mapper.CreateMap<FooDTO, FooPoco>();
        Mapper.CreateMap<DateTime?, DateTime>()
              .ConvertUsing<NullableDateTimeConverter>();
        var poco = new FooPoco();
        Mapper.Map(new FooDTO() { FooDate = null }, poco);

        if (poco.FooDate.HasValue)
            Console.WriteLine(
                "This should be null : {0}",
                poco.FooDate.Value.ToString()); //Value is always set 
        else
            Console.WriteLine("Mapping worked");
    }
}

public class NullableDateTimeConverter : ITypeConverter<DateTime?, DateTime>
{
    // Since both are nullable date times and this handles converting
    // nullable to datetime I would not expect this to be called. 
    public DateTime Convert(ResolutionContext context)
    {
        var sourceDate = context.SourceValue as DateTime?;
        if (sourceDate.HasValue)
            return sourceDate.Value;
        else
            return default(DateTime);
    }
}

我找到了这篇文章AutoMapper TypeConverter mapping nullable type to not-nullable type,但帮助不大。

【问题讨论】:

    标签: datetime automapper nullable


    【解决方案1】:

    不用看,我怀疑它会调用您的TypeCoverter,因为它与正在转换的类型最匹配。

    如果您使用正确的类型创建另一个TypeConverter,它应该可以正常工作。例如:

    public class DateTimeConverter : ITypeConverter<DateTime?, DateTime>
    {
        public DateTime Convert(ResolutionContext context)
        {
            var sourceDate = context.SourceValue as DateTime?;
            if (sourceDate.HasValue)
                return sourceDate.Value;
            else
                return default(DateTime);
        }
    }
    
    public class NullableDateTimeConverter : ITypeConverter<DateTime?, DateTime?>
    {
        public DateTime? Convert(ResolutionContext context)
        {
            var sourceDate = context.SourceValue as DateTime?;
            if (sourceDate.HasValue)
                return sourceDate.Value;
            else
                return default(DateTime?);
        }
    }
    

    请注意,如果您希望这些可以进一步简化为

    public class DateTimeConverter : TypeConverter<DateTime?, DateTime>
    {
        protected override DateTime ConvertCore(DateTime? source)
        {
            if (source.HasValue)
                return source.Value;
            else
                return default(DateTime);
        }
    }
    
    public class NullableDateTimeConverter : TypeConverter<DateTime?, DateTime?>
    {
        protected override DateTime? ConvertCore(DateTime? source)
        {
            return source;
        }
    }
    

    然后初始化两个转换器:

    Mapper.CreateMap<DateTime?, DateTime>().ConvertUsing<DateTimeConverter>();
    Mapper.CreateMap<DateTime?, DateTime?>().ConvertUsing<NullableDateTimeConverter>();
    Mapper.AssertConfigurationIsValid();
    

    【讨论】:

    • 如果您愿意,您应该可以进一步简化它,并将NullableDateTimeConverter 内联到CreateMap。没有太多收获,所以我没有打扰,但可能会让它看起来不那么 hokie :)
    猜你喜欢
    • 2016-12-19
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2019-08-30
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多