我有几个方法返回不同的泛型列表。
在。net中存在任何类静态方法或将任何列表转换为数据表?我唯一能想到的是使用反射来做到这一点。
如果我有这个:
List<Whatever> whatever = new List<Whatever>();
(这下代码当然不工作,但我想有这样的可能性:
DataTable dt = (DataTable) whatever;
我有几个方法返回不同的泛型列表。
在。net中存在任何类静态方法或将任何列表转换为数据表?我唯一能想到的是使用反射来做到这一点。
如果我有这个:
List<Whatever> whatever = new List<Whatever>();
(这下代码当然不工作,但我想有这样的可能性:
DataTable dt = (DataTable) whatever;
当前回答
如果你使用VB。NET,那么这个类就会完成这项工作。
Imports System.Reflection
''' <summary>
''' Convert any List(Of T) to a DataTable with correct column types and converts Nullable Type values to DBNull
''' </summary>
Public Class ConvertListToDataset
Public Function ListToDataset(Of T)(ByVal list As IList(Of T)) As DataTable
Dim dt As New DataTable()
'/* Create the DataTable columns */
For Each pi As PropertyInfo In GetType(T).GetProperties()
If pi.PropertyType.IsValueType Then
Debug.Print(pi.Name)
End If
If IsNothing(Nullable.GetUnderlyingType(pi.PropertyType)) Then
dt.Columns.Add(pi.Name, pi.PropertyType)
Else
dt.Columns.Add(pi.Name, Nullable.GetUnderlyingType(pi.PropertyType))
End If
Next
'/* Populate the DataTable with the values in the Items in List */
For Each item As T In list
Dim dr As DataRow = dt.NewRow()
For Each pi As PropertyInfo In GetType(T).GetProperties()
dr(pi.Name) = IIf(IsNothing(pi.GetValue(item)), DBNull.Value, pi.GetValue(item))
Next
dt.Rows.Add(dr)
Next
Return dt
End Function
End Class
其他回答
这是一个简单的混合溶液。 它适用于Nullable类型。
public static DataTable ToDataTable<T>(this IList<T> list)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
object[] values = new object[props.Count];
foreach (T item in list)
{
for (int i = 0; i < values.Length; i++)
values[i] = props[i].GetValue(item) ?? DBNull.Value;
table.Rows.Add(values);
}
return table;
}
我自己编写了一个小型库来完成这个任务。它只在将对象类型转换为数据表时第一次使用反射。它发出一个方法,该方法将完成转换对象类型的所有工作。
它燃烧得很快。你可以在这里找到它:
ToDataTable()在MoreLinq上的GitHub 原:ModelShredder在GoogleCode,被合并到MoreLinq,从GoogleCode移动到GitHub
试试这个
public static DataTable ListToDataTable<T>(IList<T> lst)
{
currentDT = CreateTable<T>();
Type entType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
foreach (T item in lst)
{
DataRow row = currentDT.NewRow();
foreach (PropertyDescriptor prop in properties)
{
if (prop.PropertyType == typeof(Nullable<decimal>) || prop.PropertyType == typeof(Nullable<int>) || prop.PropertyType == typeof(Nullable<Int64>))
{
if (prop.GetValue(item) == null)
row[prop.Name] = 0;
else
row[prop.Name] = prop.GetValue(item);
}
else
row[prop.Name] = prop.GetValue(item);
}
currentDT.Rows.Add(row);
}
return currentDT;
}
public static DataTable CreateTable<T>()
{
Type entType = typeof(T);
DataTable tbl = new DataTable(DTName);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entType);
foreach (PropertyDescriptor prop in properties)
{
if (prop.PropertyType == typeof(Nullable<decimal>))
tbl.Columns.Add(prop.Name, typeof(decimal));
else if (prop.PropertyType == typeof(Nullable<int>))
tbl.Columns.Add(prop.Name, typeof(int));
else if (prop.PropertyType == typeof(Nullable<Int64>))
tbl.Columns.Add(prop.Name, typeof(Int64));
else
tbl.Columns.Add(prop.Name, prop.PropertyType);
}
return tbl;
}
另一种方法是:
List<WhateEver> lst = getdata();
string json = Newtonsoft.Json.JsonConvert.SerializeObject(lst);
DataTable pDt = JsonConvert.DeserializeObject<DataTable>(json);
我不得不修改Marc Gravell的示例代码来处理可空类型和空值。我在下面附上了一个工作版本。谢谢你马克。
public static DataTable ToDataTable<T>(this IList<T> data)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}