将通用列表转换为C#中的数据集

我有一个通用的对象列表。 每个对象有9个字符串属性。 我想将该列表转换为可以传递给datagridview的数据集……最好的方法是什么?

您是否尝试过直接将列表绑定到datagridview? 如果没有,请首先尝试,因为它会为您节省很多痛苦。 如果您已经尝试过,请告诉我们出了什么问题,以便我们为您提供更好的建议。 数据绑定根据数据对象实现的接口提供不同的行为。 例如,如果您的数据对象仅实现IEnumerable (例如List ),您将获得非常基本的单向绑定,但如果它也实现了IBindingList (例如BindingListDataView ),那么您将获得双向绑定。

我为回答这个问题而道歉,但我认为这是查看我最终代码的最简单方法。 它包含可空类型和空值的修复程序:-)

  public static DataSet ToDataSet(this IList list) { Type elementType = typeof(T); DataSet ds = new DataSet(); DataTable t = new DataTable(); ds.Tables.Add(t); //add a column to table for each public property on T foreach (var propInfo in elementType.GetProperties()) { Type ColType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType; t.Columns.Add(propInfo.Name, ColType); } //go through each property on T and add each value to the table foreach (T item in list) { DataRow row = t.NewRow(); foreach (var propInfo in elementType.GetProperties()) { row[propInfo.Name] = propInfo.GetValue(item, null) ?? DBNull.Value; } t.Rows.Add(row); } return ds; } 

上面有Lee的扩展代码有一个错误,你需要在迭代列表中的项目时将新填充的行添加到表t中。

 public static DataSet ToDataSet(this IList list) { Type elementType = typeof(T); DataSet ds = new DataSet(); DataTable t = new DataTable(); ds.Tables.Add(t); //add a column to table for each public property on T foreach(var propInfo in elementType.GetProperties()) { t.Columns.Add(propInfo.Name, propInfo.PropertyType); } //go through each property on T and add each value to the table foreach(T item in list) { DataRow row = t.NewRow(); foreach(var propInfo in elementType.GetProperties()) { row[propInfo.Name] = propInfo.GetValue(item, null); } //This line was missing: t.Rows.Add(row); } return ds; 

}

您可以创建一个扩展方法,通过reflection添加所有属性值:

 public static DataSet ToDataSet(this IList list) { Type elementType = typeof(T); DataSet ds = new DataSet(); DataTable t = new DataTable(); ds.Tables.Add(t); //add a column to table for each public property on T foreach(var propInfo in elementType.GetProperties()) { t.Columns.Add(propInfo.Name, propInfo.PropertyType); } //go through each property on T and add each value to the table foreach(T item in list) { DataRow row = t.NewRow(); foreach(var propInfo in elementType.GetProperties()) { row[propInfo.Name] = propInfo.GetValue(item, null); } } return ds; } 

你可能想看看

http://www.codeproject.com/KB/vb/List2DataSet.aspx

提供了一些不同的方法。

蛮力代码回答你的问题:

 DataTable dt = new DataTable(); //for each of your properties dt.Columns.Add("PropertyOne", typeof(string)); foreach(Entity entity in entities) { DataRow row = dt.NewRow(); //foreach of your properties row["PropertyOne"] = entity.PropertyOne; dt.Rows.Add(row); } DataSet ds = new DataSet(); ds.Tables.Add(dt); return ds; 

现在提出实际问题。 你为什么想做这个? 如前所述,您可以直接绑定到对象列表。 也许一个仅采用数据集的报告工具?

我自己写了一个小型图书馆来完成这项任务。 它仅在第一次将对象类型转换为数据表时使用reflection。 它会发出一个方法来完成翻译对象类型的所有工作。

它是我所知道的最快的解决方案(这就是为什么我开发它:-))。 你可以在这里找到它: GoogleCode上的ModelShredder

目前它只支持翻译到DataTable。 当你提出问题时,这应该足够了。 已经开发了对DataSet的支持(想想一个简单的反向ORM),当我从假期回来时,它将在两个弱点中发布:-)

我通过处理值类型略微修改了接受的答案。 我在尝试执行以下操作时遇到此问题,因为GetProperties()的值类型为零长度,我得到一个空数据集。 我知道这不是OP的用例,但我想发布这个更改以防其他人遇到同样的事情。

 Enumerable.Range(1, 10).ToList().ToDataSet(); 

 public static DataSet ToDataSet(this IList list) { var elementType = typeof(T); var ds = new DataSet(); var t = new DataTable(); ds.Tables.Add(t); if (elementType.IsValueType) { var colType = Nullable.GetUnderlyingType(elementType) ?? elementType; t.Columns.Add(elementType.Name, colType); } else { //add a column to table for each public property on T foreach (var propInfo in elementType.GetProperties()) { var colType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType; t.Columns.Add(propInfo.Name, colType); } } //go through each property on T and add each value to the table foreach (var item in list) { var row = t.NewRow(); if (elementType.IsValueType) { row[elementType.Name] = item; } else { foreach (var propInfo in elementType.GetProperties()) { row[propInfo.Name] = propInfo.GetValue(item, null) ?? DBNull.Value; } } t.Rows.Add(row); } return ds; } 

一种选择是使用System.ComponenetModel.BindingList而不是列表。

这允许您直接在DataGridView中使用它。 与普通的System.Collections.Generic.List不同,它更新了DataGridView。

我在微软论坛上发现了这段代码。 这是迄今为止最简单的方法之一,易于理解和使用。 这节省了我的时间,我已经将它定制为扩展方法而不改变实际方法。 以下是代码。 它不需要太多解释。

您可以使用具有相同实现的两个函数签名

1)public static DataSet ToDataSetFromObject(此对象为dsCollection)

2)public static DataSet ToDataSetFromArrayOfObject(this object [] arrCollection)。 我将以此为例。

 //  // Serialize Object to XML and then read it into a DataSet: //  // Array of object // dataset public static DataSet ToDataSetFromArrayOfObject( this object[] arrCollection) { DataSet ds = new DataSet(); try { XmlSerializer serializer = new XmlSerializer(arrCollection.GetType); System.IO.StringWriter sw = new System.IO.StringWriter(); serializer.Serialize(sw, dsCollection); System.IO.StringReader reader = new System.IO.StringReader(sw.ToString()); ds.ReadXml(reader); } catch (Exception ex) { throw (new Exception("Error While Converting Array of Object to Dataset.")); } return ds; } 

在代码中使用此扩展名

 Country[] objArrayCountry = null; objArrayCountry = ....;// populate your array if ((objArrayCountry != null)) { dataset = objArrayCountry.ToDataSetFromArrayOfObject(); }