可空的日期时间到日期时间转换器automapper

时间:2013-05-02 14:33:28

标签: datetime automapper nullable

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

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,但它没什么帮助。

1 个答案:

答案 0 :(得分:7)

不看我怀疑它调用你的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();