5

我有一种情况,我的 DTO 需要DateTime属性,但我的 POCO 使用可为空的日期时间。为了避免必须为ForMember具有此条件的每个属性创建映射,我创建了一个ITypeConverter<DateTime?, DateTime>. 我遇到的问题是当 DTO 和 POCO 都具有可以为空的 DateTimes 时调用此转换器。即使该属性是可为空的日期时间也是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 将可空类型映射到不可空类型,但帮助不大。

4

1 回答 1

8

Without looking I suspect its calling your TypeCoverter because its the best match for the types being converted.

If you create another TypeConverter with the correct types it should work fine. Eg:

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?);
    }
}

Note that if you wish these can be further simplified to

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;
    }
}

Then just initialise both converters:

Mapper.CreateMap<DateTime?, DateTime>().ConvertUsing<DateTimeConverter>();
Mapper.CreateMap<DateTime?, DateTime?>().ConvertUsing<NullableDateTimeConverter>();
Mapper.AssertConfigurationIsValid();
于 2013-05-03T01:14:22.143 回答