Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将datatable转换为泛型类型的列表_C#_.net_Linq_Datatable - Fatal编程技术网

C# 将datatable转换为泛型类型的列表

C# 将datatable转换为泛型类型的列表,c#,.net,linq,datatable,C#,.net,Linq,Datatable,如何将datatable转换为泛型类型的列表。下面是场景。 我有一个名为table1的数据表,它包含col1、col2列如何将此表转换为类型名称列表table1bj(每个数据表名称可能不同),属性为col1和col2,数据类型与datatable列数据类型兼容。 有很多关于SO的帖子,但这些都是通过将datatable转换为预定义的对象列表实现的。在我的例子中,我必须从数据表生成对象并动态列出。谢谢。假设您已经创建了具有两个属性的类table1bj(由于.NET命名约定,请考虑将其设置为大写)c

如何将datatable转换为泛型类型的列表。下面是场景。 我有一个名为
table1
的数据表,它包含
col1、col2
如何将此表转换为类型名称列表
table1bj
(每个数据表名称可能不同),属性为col1和col2,数据类型与datatable列数据类型兼容。


有很多关于SO的帖子,但这些都是通过将datatable转换为预定义的对象列表实现的。在我的例子中,我必须从数据表生成对象并动态列出。谢谢。

假设您已经创建了具有两个属性的类
table1bj
(由于.NET命名约定,请考虑将其设置为大写)
col1
col2
(相同)。您只需使用
可枚举。选择
可创建此类的实例,选择
可列出
可创建通用
列表

List result=table1.AsEnumerable()
.选择(行=>new table1bj
{ 
col1=行字段(“col1”),
col1=行字段(“col1”)
}
).ToList();

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

你可以这样做

使用属性创建类:

public class table1bj
    {
        public string col1{ get; set; }
        public string col2{ get; set; }
    }
List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();
将数据表转换为泛型类型:

public class table1bj
    {
        public string col1{ get; set; }
        public string col2{ get; set; }
    }
List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();
List Objtable1bj=table1.ToCollection();

我们也可以通过反射来实现,此方法有助于通过DataTable设置类对象属性:

    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);
        }
    }
使用系统反射;
公共void SetObjectProperties(对象对象对象类,数据表DataTable)
{
DataRow_DataRow=dataTable.Rows[0];
类型objType=objClass.GetType();
List propertyList=新列表(objType.GetProperties());
foreach(dataRow.Table.Columns中的DataColumn dc)
{
var\u prop=propertyList.Where(a=>a.Name==dc.ColumnName).Select(a=>a.FirstOrDefault();
如果(_prop==null)继续;
_prop.SetValue(对象类,Convert.ChangeType(_dataRow[dc],null.getUnderlineType(_prop.PropertyType)??_prop.PropertyType),null);
}
}

我知道这个问题以前问过很多次,但我也需要一个解决方案,用一个方法将数据表转换为动态或泛型类型,我找不到答案,所以请发布我的答案

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

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;
    }

}
公共静态类扩展
{
公共静态IList ToList(此数据表dt,bool isFirstRowColumnsHeader=false),其中T:new()
{
var results=新列表();
如果(dt!=null&&dt.Rows.Count>0)
{
var columns=dt.columns.Cast().ToList();
var rows=dt.rows.Cast().ToList();
var headerNames=columns.Select(col=>col.ColumnName.ToList();
//
//查找属性名称或列名称
如果(isFirstRowColumnsHeader)
{
对于(变量i=0;i可能名为`headerNames[i]`的属性在实体中不存在,然后获取null!
.SetValue(实体,行[columns[i]]==DBNull.Value?null:行[columns[i]]);
}
}
结果:增加(实体);
}
}
}
}
返回结果;
}
}

为什么不使用实体框架?能否告诉我们如何填充数据表?用户输入?绑定到集合?@DaveRook:我们正在使用wcf服务进行数据访问layer@erajWCF数据服务和EF可以很好地结合在一起。@提姆的回答是正确的,这里只需注意的是,直接从数据库中获取<代码> Table 1BJ < /代码>。不填充中间数据表,您是否可以引用收集方法描述?它是一个扩展方法。@Sangram:但它不是框架的一部分,所以您应该