Funzioni aggregate in ADO.NET con funzionalità GROUP BY
-
06-07-2019 - |
Domanda
Questa è una domanda più diretta derivante da una precedente domanda più generale che avevo precedentemente ora che ho trascorso più tempo a cercare ADO.NET
Voglio prendere una DataTable ADO.NET ed eseguire l'equivalente di una query SQL SELECT con funzioni di aggregazione (come SUM) su alcune colonne e GROUP BY impostato per le restanti colonne. Voglio quindi prendere il risultato e visualizzarlo in un DataGrid.
Comprendo di poter creare un DataView di una DataTable che contiene criteri di filtro e funzioni di aggregazione. Ma la la pagina MSDN sulle espressioni dice che
" Se utilizzi una singola tabella per creare un aggregato, non ci sarebbe alcuna funzionalità di raggruppamento. Invece, tutte le righe mostrerebbero lo stesso valore nella colonna. & Quot;
Come posso ottenere la funzionalità di tipo GROUP BY da ADO.NET senza scrivere la mia tabella in un database separato ed eseguire una query lì? C'è un modo per farlo creando o usando una seconda tabella?
Soluzione
È possibile utilizzare l'abilità di raggruppamento di LINQ per raggiungere questo obiettivo. Inoltre, è possibile associare un DataGrid a una query LINQ, ma i dati saranno di sola lettura.
Una ricerca web per il raggruppamento LINQ dovrebbe portarti dove stai andando.
Altri suggerimenti
Un modo per aggirarlo è trasformare il risultato della tua query linq in una DataTable usando reflection. Ecco un esempio Una volta che hai una DataTable, avrai il groupby completo, il paging, ecc ...
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);
}
Ecco come farlo utilizzando .NET 3.xe versioni successive (LINQ):
http: //codecorner.galanter .net / 2009/12/17 / raggruppamento-ado-net-DataTable-con-LINQ /
Ed ecco come farlo utilizzando .NET 2.0 e versioni precedenti (standard ADP.NET)
http: // codecorner .galanter.net / 2009/04/20 / group-by-e-aggregati-in-net-DataTable /