Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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);
    }

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/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top