通过使用反射和linq到对象的数据表 [英] Datatable to object by using reflection and linq

查看:62
本文介绍了通过使用反射和linq到对象的数据表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的数据表

Name| Value
----|------
NA  |  VA
NB  |  VB
NC  |  VC1
NC  |  VC2
ND  |  VD1
ND  |  VD2

和这样的类

Class NVMapping {
  List<string> NC { get; set; }
  List<string> ND { get; set; }
  string NA { get; set; }
  string NB { get; set; }
}

如何使用linq或其他方式将数据表转换为此类型?

How to use linq or other way to transfer the datatable to this type ?

我认为我需要在这里强调一件事.这种映射将在我的应用程序中很多.

I think I need to emphasize one thing here. This kinda mapping will be a lot in my application.

我认为使用反射可以使此函数具有通用性来处理所有这些映射.

Somehow I think using reflection can make this function be generic to handle all these kinda mapping.

因此,如果可能的话,我更喜欢使用反射等通用功能来实现这一目标.

So if possible, I would prefer a generic function like using reflection to achieve this.

如果可能的话,最好像上面的转换一样将数据表传输到对象中.

If possible, it will even better just transfering datatable into an object like above transformation.

谢谢!

推荐答案

我可以建议编写一个使用反射的通用方法.以下方法使用反射从DataTable中的DataRow(或类的List<>,从DataTable中的每个DataRow中的一个)填充类的公共属性,其中ColumnName与类中公共属性的名称完全匹配(大小写-敏感的). 如果DataTable的额外列与该类中的属性不匹配,则将其忽略.如果DataTable缺少与类属性匹配的列,则将忽略该属性并将其保留为该类型的默认值(因为它是一个属性).

May I suggest writing a generic method that uses reflection. The following method uses reflection to populate a class's public properties from a DataRow in a DataTable (or a List<> of classes, one from each DataRow in the DataTable) where the ColumnName matches the name of the public property in the class exactly (case-sensitive). If the DataTable has extra columns that don't match up to a property in the class, they are ignored. If the DataTable is missing columns to match a class property, that property is ignored and left at the default value for that type (since it is a property).


    public static IList<T> DatatableToClass<T>(DataTable Table) where T : class, new()
    {
        if (!Helper.IsValidDatatable(Table))
            return new List<T>();

        Type classType = typeof(T);
        IList<PropertyInfo> propertyList = classType.GetProperties();

        // Parameter class has no public properties.
        if (propertyList.Count == 0)
            return new List<T>();

        List<string> columnNames = Table.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToList();

        List<T> result = new List<T>();
        try
        {
            foreach (DataRow row in Table.Rows)
            {
                T classObject = new T();
                foreach (PropertyInfo property in propertyList)
                {
                    if (property != null && property.CanWrite)   // Make sure property isn't read only
                    {
                        if (columnNames.Contains(property.Name))  // If property is a column name
                        {
                            if (row[property.Name] != System.DBNull.Value)   // Don't copy over DBNull
                            {
                                object propertyValue = System.Convert.ChangeType(
                                        row[property.Name],
                                        property.PropertyType
                                    );
                                property.SetValue(classObject, propertyValue, null);
                            }
                        }
                    }
                }
                result.Add(classObject);
            }
            return result;
        }
        catch
        {
            return new List<T>();
        }
    }

如果您想采用其他方法,并从类的公共属性中填写数据表,请在我的C#博客

If you interested in going the other way, and fill out a DataTable from a class's public properties, I cover that and more on my C# blog, CSharpProgramming.tips/Class-to-DataTable

这篇关于通过使用反射和linq到对象的数据表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆