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();