问题
This is a more direct question stemming from an earlier more general question i had earlier now that I've spend more time looking into ADO.NET
I want to take an ADO.NET DataTable and perform the equivalent of a SQL SELECT query with aggregate functions (such as SUM) on some columns, and GROUP BY set for the remaining columns. I then want to take the result and display it in a DataGrid.
I understand that I can create a DataView of a DataTable that contains filter criteria and aggregate functions. But the MSDN page on Expressions say that
"If you use a single table to create an aggregate, there would be no group-by functionality. Instead, all rows would display the same value in the column."
How do I get GROUP BY type functionality out of ADO.NET without writing my Table to a separate database and running a query there? Is there some way to do it by creating or using a second table?
回答1:
You can use the grouping ability of LINQ to accomplish this. Also, you can bind a DataGrid to a LINQ query, but the data will be read only.
A web search for LINQ grouping should get you where you're going.
回答2:
One way around it, is to turn your linq query result into a DataTable using reflection. Here is an example. Once you have a DataTable, you will have full groupby, paging, etc...
private static System.Data.DataTable ObjectArrayToDataTable(object[] data)
{
System.Data.DataTable dt = new System.Data.DataTable();
// if data is empty, return an empty table
if (data.Length == 0) return dt;
Type t = data[0].GetType();
System.Reflection.PropertyInfo[] piList = t.GetProperties();
foreach (System.Reflection.PropertyInfo p in piList)
{
dt.Columns.Add(new System.Data.DataColumn(p.Name, p.PropertyType));
}
object[] row = new object[piList.Length];
foreach (object obj in data)
{
int i = 0;
foreach (System.Reflection.PropertyInfo pi in piList)
{
row[i++] = pi.GetValue(obj, null);
}
dt.Rows.Add(row);
}
return dt;
}
internal static DataTable GetAllStoredFileDetailsByUserID(int userID)
{
var db = GetDataContext();
object[] result;
try
{
result = (from files in db.Files
where files.OwnerUserID == userID && files.IsThumbnail == false
select new
{
FileID = files.FileID,
Name = files.Name,
DateCreated = files.DateCreated,
Size = files.Size,
FileHits = (from act in db.FileWebActivities where act.FileID == files.FileID select act).Count()
}).ToArray();
}
catch (Exception)
{
//omitted
}
return ObjectArrayToDataTable(result);
}
回答3:
Here's how to do it using .NET 3.x and above (LINQ):
http://codecorner.galanter.net/2009/12/17/grouping-ado-net-datatable-using-linq/
And this is how to do it using .NET 2.0 and below (standard ADP.NET)
http://codecorner.galanter.net/2009/04/20/group-by-and-aggregates-in-net-datatable/
回答4:
http://weblogs.asp.net/fmarguerie/archive/2007/09/05/linq-support-on-net-2-0.aspx
来源:https://stackoverflow.com/questions/831519/aggregate-functions-in-ado-net-with-group-by-functionality