将datatable转换为泛型类型列表

时间:2013-12-13 08:53:10

标签: c# .net linq datatable

如何将数据表转换为泛型类型列表。以下是场景。 我有名称为table1的数据表,并包含col1,col2列。 我们如何将此表转换为类型名称table1bj的列表(对于每个数据表名称可以是不同的),其属性col1和col2具有兼容的数据类型,从数据表列数据类型开始。 < / p>

SO上有很多帖子,但这些帖子是将转换数据转换为预定义的对象列表。在我的情况下,我必须从数据表生成对象和动态列表。感谢。

4 个答案:

答案 0 :(得分:4)

假设您已经使用两个属性table1bjcol1(相同)创建了类col2(由于.NET命名约定而将其设为大写)。您只需使用Enumerable.Select创建此类的实例,并使用ToList创建通用List<table1bj>

List<table1bj> result = table1.AsEnumerable()
    .Select(row => new table1bj 
                       { 
                           col1 = row.Field<string>("col1"), 
                           col1 = row.Field<string>("col1") 
                       }
    ).ToList();

我还假设这些属性为string s,否则使用Field扩展方法的正确类型。如果您不知道应该使用DataTable的类型,因为它已经是具有动态类型的内存中集合。

答案 1 :(得分:1)

你可以这样做......

使用属性创建类:

public class table1bj
    {
        public string col1{ get; set; }
        public string col2{ get; set; }
    }

将DataTable转换为通用类型:

List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();

答案 2 :(得分:1)

我很多时候都知道这个问题,但是我需要一个解决方案,在一种方法中将数据表转换为动态或泛型类型,我找不到答案,所以发表我的答案。

您可以使用扩展方法将数据表转换为如下所示的任何类型:

public static class Extension
{
    public static IList<T> ToList<T>(this DataTable dt, bool isFirstRowColumnsHeader = false) where T : new()
    {
        var results = new List<T>();

        if (dt != null && dt.Rows.Count > 0)
        {
            var columns = dt.Columns.Cast<DataColumn>().ToList();
            var rows = dt.Rows.Cast<DataRow>().ToList();
            var headerNames = columns.Select(col => col.ColumnName).ToList();
            //
            // Find properties name or columns name
            if (isFirstRowColumnsHeader)
            {
                for (var i = 0; i < headerNames.Count; i++)
                {
                    if (rows[0][i] != DBNull.Value && !string.IsNullOrEmpty(rows[0][i].ToString()))
                        headerNames[i] = rows[0][i].ToString();
                }

                //
                // remove first row because that is header
                rows.RemoveAt(0);
            }

            // Create dynamic or anonymous object for `T type
            if (typeof(T) == typeof(System.Dynamic.ExpandoObject) ||
                typeof(T) == typeof(System.Dynamic.DynamicObject) ||
                typeof(T) == typeof(System.Object))
            {
                var dynamicDt = new List<dynamic>();
                foreach (var row in rows)
                {
                    dynamic dyn = new ExpandoObject();
                    dynamicDt.Add(dyn);
                    for (var i = 0; i < columns.Count; i++)
                    {
                        var dic = (IDictionary<string, object>)dyn;
                        dic[headerNames[i]] = row[columns[i]];
                    }
                }
                return (dynamic)dynamicDt;
            }
            else // other types of `T
            {
                var properties = typeof(T).GetProperties();
                if (columns.Any() && properties.Any())
                {
                    foreach (var row in rows)
                    {
                        var entity = new T();
                        for (var i = 0; i < columns.Count; i++)
                        {
                            if (!row.IsNull(columns[i]))
                            {
                                typeof(T).GetProperty(headerNames[i])? // ? -> maybe the property by name `headerNames[i]` is not exist in entity then get null!
                                    .SetValue(entity, row[columns[i]] == DBNull.Value ? null : row[columns[i]]);
                            }
                        }
                        results.Add(entity);
                    }
                }
            }
        }
        return results;
    }

}

答案 3 :(得分:0)

我们也可以通过Reflection来实现,这个方法有助于通过DataTable设置ClassObject属性:

    using System.Reflection;

    public void SetObjectProperties(object objClass, DataTable dataTable)
    {
        DataRow _dataRow = dataTable.Rows[0];
        Type objType = objClass.GetType();
        List<PropertyInfo> propertyList = new List<PropertyInfo>(objType.GetProperties());

        foreach (DataColumn dc in _dataRow.Table.Columns)
        {
            var _prop = propertyList.Where(a => a.Name == dc.ColumnName).Select(a => a).FirstOrDefault();

            if (_prop == null) continue;

            _prop.SetValue(objClass, Convert.ChangeType(_dataRow[dc], Nullable.GetUnderlyingType(_prop.PropertyType) ?? _prop.PropertyType), null);
        }
    }