将通用列表转换为 DataTable






4.33/5 (6投票s)
一个具有转换为 DataTable 功能的通用列表。
前言
在很多情况下,我们都会觉得需要将对象列表转换为 DataTable
。 我在某种情况下特别需要这个功能。
当我们在 Web 应用程序中使用面向对象的方法时,最好将 GridView
绑定到对象的泛型列表。 在这种情况下,GridView
的排序就成了一个问题,因为 C# .NET 泛型列表类没有提供简单的排序功能。
传统上(几乎所有 .NET 文章中 GridView
的排序解决方案),我们通过将源 datatable
转换为 DataView
,然后将排序后的 DataView
再次绑定到 GridView
来对 GridView
进行排序。 这对于 GridView
排序来说是一种非常简单的方法。
因此,如果我们将 GridView
绑定到对象列表,我们会觉得在排序时需要将其转换为 DataTable
。
由于泛型类 List
没有提供转换为 DataTable
的函数,我创建了一个具有此功能的 ABList
类。
因此,人们可以使用 ABList
,就像使用 List
一样,唯一的区别是增加了一个 GetDataTable
函数。
我希望现在我已经证明了撰写本文的目的,所以我们可以继续了解 ABList
的工作原理。
引言
ABList
是一个泛型类,它继承自 System.Generics.Collections.List
。 它添加了一个 public
函数 GetDataTable
,从而扩展了其功能,以获得一个 DataTable
,其中包含基础类的所有 public
属性作为列,并为列表中的每个对象都包含一行。
它可以用来创建一个任何数据类型的列表,无论是引用类型还是值类型。 如果基础类型是引用类型(String
除外),它将具有与该类的所有 public
属性相同的列。 如果它是值类型,那么将只有一个名为“Value
”的列,它将存储 List
中变量的值。
如何使用 ABList 类
使用 ABList
类就像使用 List
类一样简单。 我们需要通过提供我们想要与 ABList
类一起使用的基础类型来定义一个变量,如下所示:
ABList<Product> lstP = new ABList<Product>();
然后我们可以将项目添加到此列表,如下所示
lstP.Add(new Product("a", "a"));
lstP.Add(new Product("b", "b"));
lstP.Add(new Product("c", "c"));
就像我们使用 List
一样。
现在,如果我们想将我们的 List
转换为 DataTable
,我们只需要调用 ABClass
中定义的新函数
DataTable dtPro = lstP.GetDataTable();
ABList 类
ABList
类继承了一个泛型类 List
,它只有一个自己的函数,即 GetDataTable
函数。 以下是 ABList
的定义方式
public class ABList<T> : List<T>
很简单。
然后是 GetDataTable
函数。 我没有将 ABList
限制为仅引用类型或值类型。 因此,我们需要注意将 List
转换为 DataTable
时的两种情况,因为基础类型可以是值类型或引用类型。
首先,我们检查如果基础类型是值类型(或 string
),如何获取 DataTable
。
在值类型中,DataTable
应包含 List
中存在的所有变量(项目)的值。 因此,我们只在 DataTable
中创建一个名为“Value
”的列,并为在 List
中找到的每个项目添加一个新行,将其值保存在该行中。
if (typeof(T).IsValueType || typeof(T).Equals(typeof(string)))
{
DataColumn dc = new DataColumn("Value");
dt.Columns.Add(dc);
foreach (T item in this)
{
DataRow dr = dt.NewRow();
dr[0] = item;
dt.Rows.Add(dr);
}
}
虽然 String
是一个引用类型,但由于其行为,我们将其视为特殊情况,并且仅将其作为值类型处理。
现在,为了处理引用类型,我们需要使用 System.Reflection
命名空间的 PropertyInfo
类。
首先,我们使用反射找出基础类的所有 public
属性,如下所示
PropertyInfo[] piT = typeof(T).GetProperties();
因此,我们拥有了基础类的所有 public
属性,现在我们需要创建一个 DataTable
并将列名设置为数组 piT
中的属性名称。
foreach (PropertyInfo pi in piT)
{
//create a datacolumn for each property
DataColumn dc = new DataColumn(pi.Name, pi.PropertyType);
dt.Columns.Add(dc);
}
然后,我们遍历 List
中的所有项目,并为每个项目创建一个行,并将属性值保存在相应的列中。 为了从对象(项目)获取属性的值,我们需要为我们的 PropertyInfo piT
数组中的每个属性调用 GetValue
方法。
for (int item = 0; item < this.Count; item++)
{
DataRow dr = dt.NewRow();
for (int property = 0; property < dt.Columns.Count; property++)
{
dr[property] = piT[property].GetValue(this[item], null);
}
dt.Rows.Add(dr);
}
历史
- 2010 年 5 月 23 日:初始帖子