3

我有一个DataTable和一个Model。还有其他方法可以将列映射到班级成员吗?让我说明我目前的方式,

类模型

private class MyModel
{
    public int ModelID { get; set; }
    public string ModelName { get; set; }
}

和一个DataTable具有以下数据列,

ModelID   |   ModelName 

记录Datatable来自我的 sql 查询的结果。

SELECT ModelID, ModelName FROM tableName

现在,当我将记录映射到 时IList<MyModel> myList,我会执行一个foreach循环。

foreach (DataRow row in MyDataTable)
{
    MyModel model = new MyModel()
    model.ModelID = Convert.ToInt32(row["Position"].ToString());
    model.ModelName = row["ModelName"].ToString(); 
    myList.Add(model);
}

这完全可以正常工作。这不是一个真正的问题,但考虑到我有许多数据表并且有20 列或更多列以及更多类,这非常耗时。

我正在寻找的是是否有其他方法可以做到这一点。就像一个现有的课程,但我真的不知道它的名字是什么。

如果已经问过这个问题,请帮我找到链接。

谢谢你。

4

2 回答 2

2

AutoMapper应该能够做到这一点,尽管您需要测试它的效率。 这篇文章似乎取得了一些成功:

public class Person
{
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
    public string User_Name { get; set; }
}

List<Person> people = AutoMapper.Mapper.DynamicMap<IDataReader, 
                      List<Person>>(sourceDataTable.CreateDataReader());

请注意,在幕后,它可能正在做一些与您已经在做的事情非常相似的事情,但是混合了一些反射以使其更通用。你正在做的事情本身并不是非常低效,除非你在谈论非常高的音量并且需要挤出每一盎司可能的性能。

DataTable用 ORM 完全 替换它也可能对您有用。实体框架是一个非常常见的标准,尽管还有很多其他标准。(Dapper以其快速的性能而闻名,如果您正在寻找的话。)

如果“耗时”的部分不是运行时性能而是开发时间,我不会太担心它。如果您可以花一些时间将DataTable翻译层后面的 s 抽象为 POCO 对象,那么从长远来看,这些好处可能会得到回报。这是很多琐碎的代码,但这是一次性的费用。

于 2013-10-02T13:13:42.497 回答
0

你可以使用这个。

public static List<T> ToModel<T>(this DataTable dt)
    {
        List<string> columns = (from DataColumn dc in dt.Columns select dc.ColumnName).ToList();

        var fields = typeof(T).GetFields();
        var properties = typeof(T).GetProperties();

        List<T> lst = new List<T>();

        foreach (DataRow dr in dt.Rows)
        {
            var ob = Activator.CreateInstance<T>();

            foreach (var fieldInfo in fields.Where(fieldInfo => columns.Contains(fieldInfo.Name)))
            {
                fieldInfo.SetValue(ob, !dr.IsNull(fieldInfo.Name) ? dr[fieldInfo.Name] : fieldInfo.FieldType.IsValueType ? Activator.CreateInstance(fieldInfo.FieldType) : null);
            }

            foreach (var propertyInfo in properties.Where(propertyInfo => columns.Contains(propertyInfo.Name)))
            {
                propertyInfo.SetValue(ob, !dr.IsNull(propertyInfo.Name) ? dr[propertyInfo.Name] : propertyInfo.PropertyType.IsValueType ? Activator.CreateInstance(propertyInfo.PropertyType) : null);
            }

            lst.Add(ob);
        }

        return lst;
    }
于 2015-07-28T08:27:02.077 回答