如何动态地将LINQ查询结果转换为DataTable?
问题描述:
如何动态地将LINQ查询结果转换为DataTable?如何动态地将LINQ查询结果转换为DataTable?
有些解决方案可以创建另一个类并指定列名,但我希望能够灵活地更改LINQ结构(如列名,列数),并自动生成带有列名的DataTable。
感谢
答
我已经包含了一个扩展方法,我使用SqlBulkCopy来完成这个工作,但是我想问你为什么要这个转换。数量有限的情况下(SqlBulkCopy是一个),其中一个对象列表不能做一切数据表可以。您可以将它们用作大多数控件的绑定源......只是好奇。
public static DataTable toDataTable<T>(this IEnumerable<T> value, List<string> exclusionList)
where T : class
{
var dataTable = new DataTable();
var type = typeof(T);
var properties = type.GetProperties().Where(x => !exclusionList.Contains(x.Name)).ToList();
foreach (var propertyInfo in properties)
{
var propertyType = propertyInfo.PropertyType;
if (!propertyType.IsScalar())
continue;
var nullableType = Nullable.GetUnderlyingType(propertyType);
propertyType = nullableType ?? propertyType;
var dataColumn = new DataColumn(propertyInfo.Name, propertyType);
if (nullableType != null)
dataColumn.AllowDBNull = true;
dataTable.Columns.Add(dataColumn);
}
foreach (var row in value)
{
var dataRow = dataTable.NewRow();
foreach (var property in properties)
{
var safeValue = property.GetValue(row, null) ?? DBNull.Value;
dataRow[property.Name] = safeValue;
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
答
他们关键是使用LINQ查询结果作为其实现IList接口。 如果您收到的结果作为一个参数上的方法作为一个IList对象,你可以访问它的行和列,这样说:
var props = item.GetType().GetProperties();
参考这个例子中,它是一个小类请你只注意它抽象DataTable的创建,并且里面有一个叫做“LINQToDataTable”的静态方法,你应该使用它。
-
步骤1,创建一个名为 “GridHelper” 类(使用System.Data DataTable的用于结构)
public class GridHelper { private DataTable baseDt; public GridHelper(string tableName) { baseDt = new DataTable(tableName); } public DataTable getDataTable() { return baseDt; } public object[,] getObjToFill() { object[,] obj = new object[baseDt.Columns.Count, 2]; for (int i = 0; i < baseDt.Columns.Count; i++) { obj[i, 0] = baseDt.Columns[i].ColumnName; } return obj; } public void addColumn(string colName, Type valueType) { baseDt.Columns.Add(colName, valueType); } public void addRow(object[,] values) { DataRow newRow = baseDt.NewRow(); for (int i = 0; i < values.Length/2; i++) { bool colFound = false; for (int j = 0; j < baseDt.Columns.Count; j++) { if (baseDt.Columns[j].ColumnName == values[i, 0].ToString()) { colFound = true; break; } } if (colFound == false) { throw new Exception("The column " + values[i, 0].ToString() + " has not been added yet."); } newRow[values[i, 0].ToString()] = values[i, 1]; } baseDt.Rows.Add(newRow); } public static DataTable LINQToDataTable<T>(T objToList) where T : System.Collections.IList { GridHelper ghResult = new GridHelper("Report"); foreach (Object item in objToList) { var props = item.GetType().GetProperties(); foreach (var prop in props) { ghResult.addColumn(prop.Name, typeof(string)); //prop.Name //prop.GetValue(item) } break; } object[,] obj = ghResult.getObjToFill(); foreach (Object item in objToList) { var props = item.GetType().GetProperties(); int index = 0; foreach (var prop in props) { //ReportValue(prop.Name, prop.GetValue(item, null)); //prop.Name obj[index, 1] = prop.GetValue(item); index++; } ghResult.addRow(obj); } return ghResult.getDataTable(); } }
-
用法:
var listaReporte = (from t in dbContext.TablaPruebas select new { Name = t.name, Score = t.score } ) .ToList(); DataTable dt = Library.GridHelper.LINQToDataTable(listaReporte);
,那就是,用你的数据表如您所愿,在GridView或DataGridView上
答
查看MoreLinq Nuget包。它有一个功能ToDataTable()
var LinqResults = from ......;
DataTable dt_Results = LinqResults.ToDataTable();
https://code.google.com/p/morelinq/
它具有其他非常有用的功能,以及: https://code.google.com/p/morelinq/wiki/OperatorsOverview
让我们假设你有一个图书馆一类检索使用LINQ从数据库中的信息,您想要返回不同类型的项目,如Windows Form(DataGridView),Web Form(GridView)等可以显示信息的结果,您不能返回Anonymous类型的列表。我试图使用你的扩展,但我不知道IsScalar()是在哪里声明的。 – 2014-10-31 16:57:02
标量是在另一个库中,你可以把它拉出来 – 2014-10-31 17:03:07