使用AutoMapper将DataRow转换为对象

7

我可以成功地将IDataReader映射到对象列表中,但是当我想要选择一个DataRow时,它似乎并没有按照预期工作。

这里我有什么简单的遗漏吗?

[TestFixture]
public class AutomapperTest
{
    [Test]
    public void TestMethod1()
    {
        DataTable dt = new DataTable("contact");
        dt.Columns.Add("FirstName");
        dt.Columns.Add("LastName");
        dt.Columns.Add("Line1");
        dt.Columns.Add("Line2");
        dt.Columns.Add("Line3");
        dt.Columns.Add("Suburb");
        dt.Columns.Add("State");
        dt.Columns.Add("Postcode");

        DataRow row = dt.NewRow();
        row.ItemArray = new [] { "Little", "Johnny", 
                                 "1 Random Place", "", "", 
                                 "Windsor", "Qld", "4030" };

        var dest = Mapper.DynamicMap<myObject>(row);

        Assert.AreEqual(row["FirstName"], "Little");
        Assert.IsNotNull(dest);
        Assert.AreEqual(dest.FirstName, "Little");
    }
}

目标类型:

public class myObject
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string Line3 { get; set; }
    public string Suburb { get; set; }
    public string State { get; set; }
    public string Postcode { get; set; }
}
2个回答

11
你需要实现自己的定制值解析器。 https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers 更新
public class CustomResolver : IValueResolver
{
    public ResolutionResult Resolve(ResolutionResult source)
    {
        return source.New( Convert.ChangeType((source.Context.SourceValue as DataRow)[source.Context.MemberName], source.Context.DestinationType));
    }
}

以下是如何使用它的方法

Mapper.CreateMap<DataRow,myObject>().ForAllMembers(m=>m.ResolveUsing<CustomResolver>());
var dest = Mapper.Map<myObject>(row);

我建议使用Dapper。这样,从数据库中获取的数据将是强类型或动态类型的,并且Automapper应该能够找到映射。

我认为可以通过ODBC使Dapper读取CSV文件。但是对于CSV文件,我建议使用LinqToCSV Nuget包。


考虑使用Dapper和Automapper。 - Darek
你能举个例子说明自定义值解析器在这里如何帮助吗? - Sergey Berezovskiy
@SergeyBerezovskiy 这个示例可以吗? - Darek
2
尝试使用更改的接口使其在版本5.0.2上运行,维护者说“AutoMapper不支持此场景。” - PJ7
你能发布一个新的案例并提供链接吗? - Darek
显示剩余2条评论

0
另一种方法是使用ITypeConverter:
创建一个自定义的TypeConverter类:
public class DataRowConverter : ITypeConverter<DataRow, Object>
{
    Object ITypeConverter<DataRow, Object>.Convert(DataRow source, Object destination, ResolutionContext context)
    {
        foreach (DataColumn col in source.Table.Columns)
        {
            var value = source[col].ToString();

            PropertyInfo prop = destination.GetType().GetProperty(
                col.ColumnName,
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.IgnoreCase);

            if (prop != null && prop.CanWrite)
            {
                prop.SetValue(destination, value, null);
            }
        }

        return destination;
    }
}

然后设置配置:

cfg.CreateMap<DataRow, Object>().ConvertUsing<DataRowConverter>();

最后,像往常一样使用映射器:
var results = new List<SearchResult>();
foreach (DataRow row in Res.data.Tables[0].Rows)
{
    var obj = mapper.Map<SearchResult>(row);
    results.Add(obj);
}

它应该与最新版本的AutoMapper一起工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接