使用Automapper将字符串转换为DataReader中的bool

时间:2013-02-06 21:29:39

标签: c# .net automapper

这似乎是一个非常简单的问题,所以希望这很容易。

我在Automapper中有一个自定义的stringbool地图,只是将"Y""N"转换为truefalse。它没有那么简单:

Mapper.CreateMap<string, bool>().ConvertUsing(str => str.ToUpper() == "Y");

这个原始示例中的工作正常:

public class Source
{
    public string IsFoo { get; set; }
    public string Bar { get; set; }
    public string Quux { get; set; }
}

public class Dest
{
    public bool IsFoo { get; set; }
    public string Bar { get; set; }
    public int Quux { get; set; }
}

// ...

Mapper.CreateMap<string, bool>().ConvertUsing(str => str.ToUpper() == "Y");
Mapper.CreateMap<Source, Dest>();
Mapper.AssertConfigurationIsValid();

Source s = new Source { IsFoo = "Y", Bar = "Hello World!", Quux = "1" };
Source s2 = new Source { IsFoo = "N", Bar = "Hello Again!", Quux = "2" };
Dest d = Mapper.Map<Source, Dest>(s);
Dest d2 = Mapper.Map<Source, Dest>(s2);

但是,我想说我想从Source获取DataReader数据:

Mapper.CreateMap<string, bool>().ConvertUsing(str => str.ToUpper() == "Y");
Mapper.CreateMap<IDataReader, Dest>();
Mapper.AssertConfigurationIsValid();

DataReader reader = GetSourceData();
List<Dest> mapped = Mapper.Map<IDataReader, List<Dest>>(reader);

对于Dest中的每个mappedIsFoo属性为true。我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

我最终放弃了stringbool地图,而是为IMemberConfigurationExpression<IDataReader>创建了扩展方法。 扩展方法复数,因为我也遇到this issue,其中从DB返回的数值数据与目标类型完全不匹配,导致大数字不一致。由于数据库的东西不受我的控制,我不得不强迫映射器将其读作某种类型。所以这就是我最终的结果:

public static class Mapping
{
    public static void Init()
    {
        Mapper.CreateMap<IDataReader, Dest>()
            .ForMember(s => s.IsFoo, opt => opt.ReadAsBoolean("IsFoo"))
            .ForMember(s => s.Quux, opt => opt.ReadAsNumber("Quux"));

        Mapper.AssertConfigurationIsValid();
    }

    public static void ReadAsBoolean(this IMemberConfigurationExpression<IDataReader> opt, string fieldName)
    {
        opt.MapFrom(reader => reader.GetString(reader.GetOrdinal(fieldName)).ToUpper() == "Y");
    }

    public static void ReadAsNumber(this IMemberConfigurationExpression<IDataReader> opt, string fieldName)
    {
        opt.MapFrom(reader => reader.GetDecimal(reader.GetOrdinal(fieldName)));
    }
}

作为字符串的属性名称的复制违背我的要求,但我怀疑具有更多Automapper技能的人可以使其更优雅。现在,这至少有效。

答案 1 :(得分:0)

IDataReader内,数据存储为对象而不是字符串。所以我假设AutoMapper正在评估任何非空的true