我使用的是.NET 3.5,需要将以下选择的新结果转换为DataTable。是否有内置的东西或任何人都知道可以做到这一点的方法?
var contentList = (from item in this.GetData().Cast<IContent>()
select new
{
Title = item.GetMetaData("Title"),
Street = item.GetMetaData("Street"),
City = item.GetMetaData("City"),
Country = item.GetMetaData("Country")
});
答案 0 :(得分:7)
简单直接的做法是使用反射:
var records = (from item in this.GetData().Cast<IContent>()
select new
{
Title = "1",
Street = "2",
City = "3",
Country = "4"
});
var firstRecord = records.First();
if (firstRecord == null)
return;
var infos = firstRecord.GetType().GetProperties();
DataTable table = new DataTable();
foreach (var info in infos) {
DataColumn column = new DataColumn(info.Name, info.PropertyType);
table.Columns.Add(column);
}
foreach (var record in records) {
DataRow row = table.NewRow();
for (int i = 0; i < table.Columns.Count; i++)
row[i] = infos[i].GetValue(record);
table.Rows.Add(row);
}
代码可能没有预先准备好,但应该给你一个大概的想法。首先,从匿名类型获取propertyInfos并使用此元数据创建数据表模式(填充列)。然后使用这些信息从每个对象获取值。
答案 1 :(得分:3)
这是一个没有反映属性的通用解决方案。有一个扩展方法如下
public static DataTable ConvertToDataTable<TSource>(this IEnumerable<TSource>
records, params Expression<Func<TSource, object>>[] columns)
{
var firstRecord = records.First();
if (firstRecord == null)
return null;
DataTable table = new DataTable();
List<Func<TSource, object>> functions = new List<Func<TSource, object>>();
foreach (var col in columns)
{
DataColumn column = new DataColumn();
column.Caption = (col.Body as MemberExpression).Member.Name;
var function = col.Compile();
column.DataType = function(firstRecord).GetType();
functions.Add(function);
table.Columns.Add(column);
}
foreach (var record in records)
{
DataRow row = table.NewRow();
int i = 0;
foreach (var function in functions)
{
row[i++] = function((record));
}
table.Rows.Add(row);
}
return table;
}
并使用where参数作为所需顺序的列名来调用相同的内容。
var table = records.ConvertToDataTable(
item => item.Title,
item => item.Street,
item => item.City
);
答案 2 :(得分:0)
有CopyToDataTable
extension method为您做到这一点。它位于System.Data.DataSetExtensions.dll
答案 3 :(得分:0)
试试这个:
// Create your datatable.
DataTable dt = new DataTable();
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("Street", typeof(double));
// get a list of object arrays corresponding
// to the objects listed in the columns
// in the datatable above.
var result = from item in in this.GetData().Cast<IContent>()
select dt.LoadDataRow(
new object[] { Title = item.GetMetaData("Title"),
Street = item.GetMetaData("Street"),
},
false);
// the end result will be a set of DataRow objects that have been
// loaded into the DataTable.
代码示例的原始文章:Converting Anonymous type generated by LINQ to a DataTable type
编辑:通用伪代码:
void LinqToDatatable(string[] columns, Type[] datatypes, linqSource)
{
for loop
{
dt.columns.add(columns[i], datatypes[i]);
}
//Still thinking how to make this generic..
var result = from item in in this.GetData().Cast<IContent>()
select dt.LoadDataRow(
new object[] { string[0] = item.GetMetaData[string[0]],
string[1] = item.GetMetaData[srring[1]
},
false);
}
答案 4 :(得分:0)
您可以通过以下函数将列表结果转换为数据表
public static DataTable ToDataTable<T>(IEnumerable<T> values)
{
DataTable table = new DataTable();
foreach (T value in values)
{
if (table.Columns.Count == 0)
{
foreach (var p in value.GetType().GetProperties())
{
table.Columns.Add(p.Name);
}
}
DataRow dr = table.NewRow();
foreach (var p in value.GetType().GetProperties())
{
dr[p.Name] = p.GetValue(value, null) + "";
}
table.Rows.Add(dr);
}
return table;
}
答案 5 :(得分:0)
public static DataTable ListToDataTable<T>(this IList<T> data)
{
DataTable dt = new DataTable();
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
dt.Columns.Add(prop.Name, prop.PropertyType);
}
object[] values = new object[props.Count];
foreach (T t in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(t);
}
dt.Rows.Add(values);
}
return dt;
}
完成新选择后,您可以.ToList().ListToDataTable()
。这使用ComponentModel反射,并且(理论上)比System.Reflection快。