[C#] Raggruppare oggetti di un datatable

mercoledì 07 gennaio 2009 - 17.02

liveforever81 Profilo | Junior Member

Salve a tutti.

Ho un Datatable che ha un numero imprecisato di righe ma colonne di cui conosco il numero ed il nome.

Volevo creare a livello di codice un metodo che mi consentisse di avere raggruppate le righe.

Esempio: ho una colonna nominata "COGNOME";
ebbene, vorrei che il Datatable risultante sia ordinato raggruppando le righe in "blocchi" per cognome...

cosa usereste voi?

Grazie a tutti!

rossimarko Profilo | Guru

Ciao,

in che senso vuoi il datatable raggruppato?

Puoi sfruttare delle classi che ti facciano un groupby tipo quella riportata qui: http://support.microsoft.com/kb/325685

Oppure puoi usi le datarelation e quindi crei due datatable, una con i dati di intestazione (magari ottenuta con una distinct http://support.microsoft.com/kb/326176) e una con tutte le righe. Poi puoi creare una DataRelation (http://msdn.microsoft.com/it-it/library/system.data.datarelation.aspx) tra la tabella principale e la secondaria, così mentre scorri tutte le righe della tabella principale puoi reperire quella della tabella secondaria: http://msdn.microsoft.com/en-us/library/system.data.datarow.getchildrows.aspx
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko

liveforever81 Profilo | Junior Member

Ciao Marco,
grazie come al solito per la celere risposta.

Ti spiego il mio problema: Ho un DataTable di Anagrafica in cui riporto, ad esempio, Nome, Cognome, età e Città Natale.
Le righe possono essere di numero variabile e all'inizio non so quante città natali differenti posso avere.

Inizialmente il Datatable viene visualizzato non in un ordine preciso (nel senso che le righe non seguono un particolare ordinamento ma sono semplicemente visualizzate sulla base della data di inserimento).

La pressione di un ImageButton appropriato deve scatenare ciò di seguito:

Viene creato un Header che visualizza solo il nome della città natale (in modo che l'utente veda sola la lista delle città);
Cliccando sulla città natale si espanderà l'header (questo avrei intenzione di implementarlo in javascript) e verrà fuori la lista di tutti i tizi, cai e semproni che appartengono a quella città (finalmente ordinati).

Ti è chiaro ora?

Avevo pensato di usare un ArrayList per ciascuna città: ciclo per ogni riga e metto quella riga nell'ArrayList appropriato.
Ho pensato che è meglio nn usare un ordinamento sul datatable dato che poi a me interessa solo un sottoinsieme dello stesso.

Che mi consigli (consigliate)?

Grazie mille

rossimarko Profilo | Guru

Ciao,

allora puoi usare la soluzione delle due datatable. Nella prima solo i dati da visualizzare nell'intestazione, nella seconda quelli di dettaglio. Per caricare i dati di intestazioni puoi usare il metodo distinct.

Altrimenti se vuoi usare dei tuoi oggetti crei una collection che conterrà solo i dati delle intestazioni, e poi al click del pulsante di espansione vai a ricercare nella datatable tutte le righe che hanno come "idpadre" l'elemento selezionato. La datatable possiede ad esempio un metodo select per fare questo: http://msdn.microsoft.com/it-it/library/system.data.datatable.select.aspx

Comunque considera che con le opzioni che ti ho elencato stai caricando dei dati che non ti servono, nel senso che carichi tutti i dati e poi ne estrai solo una parte.
Sarebbe meglio allora suddividere la select con tutti i dati in due chiamate, una con i dati raggruppati e una che carica solo i dati del raggruppamento selezionato, in questo modo carichi i dati solo quando ti serve. Farai una chiamata in più su db, però riguarderà solo un subset di dati. Vedi tu in base alla tua architettura cosa è meglio.
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko

liveforever81 Profilo | Junior Member

Ciao Marco,

credo che userò la tua soluzione.

Ora però mi han detto "cosa" usare: questo datatable visualizzato (che io "filtrerò") è parte di un Web Control.

Il Datatable da me filtrato dovrà essere "contenuto" in un WebControl apposito che verrà lanciato ogni volta che verrà premuto un bottoncino apposito.

La mia domanda è:
- Nella pagina .aspx vi è il riferimento al primo webcontrol:
<AALista: AABox ID.....>
Vi è poi il file AABox.cs che espone il controllo.
- Dovendo io creare questo nuovo controllo, posso aggiungerlo in quella pagina .aspx semplicemente aggiungendo un nuovo tag?
- Devo successivamente creare una classe con lo stesso nome dell'ID nella quale creo la tabella, giusto?

Sono poco pratico di WebControl...:p

Grazie mille ancora

rossimarko Profilo | Guru

Quando crei il webcontrol ti crea in automatico sia il file ascx che la classe associata.

nel file ascx c'è l'html, mentr nel cs il codice associato

Poi per usarlo nella pagina devi registrarlo nell'intestazione:
<%@ Register TagPrefix="" TagName="" Src="" %>
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko

liveforever81 Profilo | Junior Member

Perdonami: qui si parla di WebControls e non WebUserControls; se non sbaglio c'è una differenza (tant'è che nel progetto non esiste alcun file .ascx ma solo l'aspx con alcuni classi associate)

rossimarko Profilo | Guru

>Perdonami: qui si parla di WebControls e non WebUserControls;
>se non sbaglio c'è una differenza (tant'è che nel progetto non
>esiste alcun file .ascx ma solo l'aspx con alcuni classi associate)

Scusami, avevo letto male. In tal caso allora dovrai creare la classe e basta (il luogo in cui crearla non fa differenza) che eredita da WebControl o dalla classe che più ti aggrada. Poi dovrai registrarla all'interno della pagina inserendo invece che il tag src, l'assembly dove è salvata e il relativo namespace.
Automaticamente verranno caricate tutte le classi all'interno del namespace utilizzabili come controlli
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko

liveforever81 Profilo | Junior Member

Bene, fammi controllare se ho capito.

Ora ho una cosa del genere:

[pagina .aspx]
<Register TagPrefix="AAList" Namespace="Folder" Assembly...>

<AAList:Box ID="_list" runat="server" /> /******

[Ho poi 4 classi chiamate Box, Proxy, Pane e Item]
Tutte e 4 queste classi ereditano da WebControl e sn tutte nel namespace Folder.

Creo quindi la mia classe che eredita anch'essa da WebControl.
Poichè però questo qui è un differente controllo, devo aggiungere un altro Register ed un'altra riga (simile a quella /*****) nella pagina aspx?

rossimarko Profilo | Guru

>Creo quindi la mia classe che eredita anch'essa da WebControl.
>Poichè però questo qui è un differente controllo, devo aggiungere
>un altro Register ed un'altra riga (simile a quella /*****) nella
>pagina aspx?

No, se l'assembly e il namespace sono gli stessi la classe verrà caricata (ovviamente deve essere public).
Se ad esempio la classe si chiama Pippo invece che <AAList:Box dovrai scrivere <AAList:Pippo per usare il controllo
-----------------------------------------
Rossi Marco
http://blogs.dotnethell.it/rossimarko
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5