Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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# 将数据表转换为列表<;T>;_C#_.net_Generics_Ado.net_Datatable - Fatal编程技术网

C# 将数据表转换为列表<;T>;

C# 将数据表转换为列表<;T>;,c#,.net,generics,ado.net,datatable,C#,.net,Generics,Ado.net,Datatable,我有一个疑问,有时我从DataTable转换为List: 有什么建议吗 我之所以需要这样做,是因为结果的每个数据行都需要转换为一个实体,以便更好地进行操作。它本身不便于转换,您可以这样做,但可能不会节省很多工作 考虑代码示例中的内在知识:您知道DataTable中每个列的类型和名称,以及它在输出类型中映射到的属性的类型和名称。另一种方法是知道每列的类型和索引(用名称代替索引)。在这两种情况下,您都需要定义一个映射来包含该信息 另一种方法是构建一个基于约定的转换器——换句话说,您的数据表列名及其目

我有一个疑问,有时我从
DataTable
转换为
List

有什么建议吗


我之所以需要这样做,是因为结果的每个数据行都需要转换为一个实体,以便更好地进行操作。

它本身不便于转换,您可以这样做,但可能不会节省很多工作

考虑代码示例中的内在知识:您知道
DataTable
中每个列的类型和名称,以及它在输出类型中映射到的属性的类型和名称。另一种方法是知道每列的类型和索引(用名称代替索引)。在这两种情况下,您都需要定义一个映射来包含该信息


另一种方法是构建一个基于约定的转换器——换句话说,您的
数据表
列名及其目标属性需要统一命名,偏离该约定将导致转换失败。

您正在寻找这样的东西吗

public static List<T> ConvertDS<T>(DataSet ds, Converter<DataRow, T> converter)
{
    return
        (from row in ds.Tables[0].AsEnumerable()
         select converter(row)).ToList();
}
公共静态列表转换器ds(数据集ds,转换器)
{
返回
(来自ds.Tables[0]中的行。可计算()
选择转换器(行)).ToList();
}

好的,让我们玩一玩:

public static class DataTableExtensions
{
    public static List<T> ToGenericList<T>(this DataTable datatable, Func<DataRow, T> converter)
    {
        return (from row in datatable.AsEnumerable()
                select converter(row)).ToList();
    }
}

class EDog
{
    private int intIdDog;
    private int intIdOwner;
    private int intAge;
    private string strName;

    ...

    public static EDog Converter(DataRow row)
    {
        return new EDog
                        {
                            intIdDog = (int)row["IdDog"],
                            intIdOwner = (int)row["IdOwner"],
                            intAge = (int)row["Age"],
                            strName = row["Name"] as string
                        };
    }
}
公共静态类DataTableExtensions
{
公共静态列表到通用列表(此DataTable、DataTable、Func转换器)
{
返回(来自datatable.AsEnumerable()中的行)
选择转换器(行)).ToList();
}
}
类EDog
{
私人int intIdDog;
私人内特唐纳;
私人进口;
私有字符串strName;
...
公共静态EDog转换器(数据行)
{
返回新的EDog
{
intIdDog=(int)行[“IdDog”],
IntitDowner=(int)行[“IdOwner”],
intAge=(int)行[“年龄”],
strName=行[“名称”]作为字符串
};
}
}
用法:

List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>(EDog.Converter);
List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>();
List dogs=dsDogs.Tables[0].ToGenericList(EDog.Converter);
但是没有足够的乐趣,对吗?那么这个呢:

class DataRowKeyAttribute : Attribute
{
    private readonly string _Key;

    public string Key
    {
        get { return _Key; }
    }

    public DataRowKeyAttribute(string key)
    {
        _Key = key;
    }
}


static class DataTableExtensions
{
    public static List<T> ToGenericList<T>(this DataTable datatable) where T : new()
    {
        return (from row in datatable.AsEnumerable()
                select Convert<T>(row)).ToList();
    }

    private static T Convert<T>(DataRow row) where T : new()
    {
        var result = new T();

        var type = result.GetType();

        foreach (var fieldInfo in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        {
            var dataRowKeyAttribute = fieldInfo.GetCustomAttributes(typeof (DataRowKeyAttribute), true).FirstOrDefault() as DataRowKeyAttribute;
            if (dataRowKeyAttribute != null)
            {
                fieldInfo.SetValue(result, row[dataRowKeyAttribute.Key]);
            }
        } 

        return result;
    }
}

class EDog
{
    [DataRowKey("IdDog")]
    private int intIdDog;
    [DataRowKey("IdOwner")]
    private int intIdOwner;
    [DataRowKey("Age")]
    private int intAge;
    [DataRowKey("Name")]
    private string strName;

    ... 
}
class DataRowKeyAttribute:属性
{
私有只读字符串\u密钥;
公共字符串密钥
{
获取{return\u Key;}
}
公共DataRowKeyAttribute(字符串键)
{
_钥匙=钥匙;
}
}
静态类DataTableExtensions
{
公共静态列表ToGenericList(此数据表),其中T:new()
{
返回(来自datatable.AsEnumerable()中的行)
选择Convert(row)).ToList();
}
私有静态T Convert(DataRow行),其中T:new()
{
var结果=新的T();
var type=result.GetType();
foreach(type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)中的var fieldInfo)
{
var dataRowKeyAttribute=fieldInfo.GetCustomAttributes(typeof(dataRowKeyAttribute),true);
如果(dataRowKeyAttribute!=null)
{
fieldInfo.SetValue(结果,行[dataRowKeyAttribute.Key]);
}
} 
返回结果;
}
}
类EDog
{
[数据行键(“IdDog”)]
私人int intIdDog;
[DataRowKey(“IdOwner”)]
私人内特唐纳;
[数据行键(“年龄”)]
私人进口;
[数据行键(“名称”)]
私有字符串strName;
... 
}
用法:

List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>(EDog.Converter);
List<EDog> dogs = dsDogs.Tables[0].ToGenericList<EDog>();
List dogs=dsDogs.Tables[0].ToGenericList();

如果您想获得真正的乐趣,请添加错误处理,考虑缓存反射数据以提高性能并将字段更改为属性。

< P>我可以在一行代码中执行: dt是数据表

List<DataRow> alist = new dt.AsEnumerable().ToList();
List alist=new dt.AsEnumerable().ToList();

如何将数据表转换为通用列表:谢谢,但不要使用foreach语句。或者:确切地说,谢谢,这是我实际做的,然后我对转换器方法逐行进行了相反的操作。谢谢你。这个问题没有答案。需求是生成类型化对象列表(本例中为EDog),而不是DataRow列表。
List<DataRow> alist = new dt.AsEnumerable().ToList();