Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it L'avatar di exFelino
    Registrato dal
    Jul 2014
    residenza
    Aci Catena (CT)
    Messaggi
    710

    [C#][LINQ] Creare un Dictionary da un DataTable

    Sera a tutti,
    ho un datatable formato da N colonne, due delle quali sono 'tipo' e 'colore'.

    Avrei la necessità di popolare un Dictionary eseguendo un distinct sul dataTable per 'tipo' e tirando fuori i colori ad esso associati.

    Ho semplicemente scritto:
    codice:
    Dictionary<String, String> listOfTypeColours = new Dictionary<String, String>();
    
    listOfTypeColours = fs.DataTable.AsEnumerable().Distinct()
                                                   .ToDictionary(
                                                        row => row.Field<String>('Tipo'),
                                                        row => row.Field<String>('Colore')
                                                    );
    ma non riesco ad eseguire la distinct per 'tipo'.

    Potreste aiutarmi?

    Grazie

  2. #2
    Utente di HTML.it L'avatar di exFelino
    Registrato dal
    Jul 2014
    residenza
    Aci Catena (CT)
    Messaggi
    710
    Oppure potrei prima eseguire un distinct per ricavare i 'tipi' presenti....ma dopo come posso eseguire un iterator per ricavare il 'colore' corrispondente?

    codice:
    List<string> arrType = fs.DataTable.AsEnumerable().Select(row => row.Field<String>('Tipo')).Distinct().ToList();
    Grazie.

  3. #3
    Utente di HTML.it L'avatar di exFelino
    Registrato dal
    Jul 2014
    residenza
    Aci Catena (CT)
    Messaggi
    710
    Ragazzi, ho trovato questa soluzione funzionante:
    codice:
    Dictionary<String, String> listOfTypeColours = new Dictionary<String, String>();                
    				
    List<string> arrType = fs.DataTable.AsEnumerable().Select(row => row.Field<String>('TIPO')).Distinct().ToList();
    
    
    foreach (string item in arrType)
    {
    	string myKey = fs.DataTable.AsEnumerable().Where(row => row.Field<String>('TIPO').Equals(item))
    											  .Select(row => row.Field<String>('COLORE')).First();
    
    
    	listOfTypeColours.Add(item, myKey); 
    }
    .

    Se comunque esiste un modo per eseguire un distinct sul DataTable e da esso ricavare un Dictionary, potreste indicarmelo?

    Grazie.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2015
    Messaggi
    57
    c'è fondamentalmente qualcosa di sbagliato in quello che cerchi di fare
    ammettendo che tu abbia una situazione del genere, con tutte le possibilità del caso

    data.jpg

    utilizzando il tuo codice perdi elementi
    codice:
    List<string> arrType = fs.DataTable.AsEnumerable().Select(row => row.Field<String>('TIPO')).Distinct().ToList();
    con il select prelevi tutti gli elementi in una nuova lista in forma di stringa,
    in seguito esegui il distinct per rimuovere i doppioni,
    questo lo fai perchè senza il select il distinct verebbe eseguito sul riferimento e non sul valore,
    mentre senza il distinct il select conterrebbe sempre tutti gli elementi.
    in seguito vai a iterare sugli elementi stringa di tipo distinti, da qui ricerchi nuovamente in tutti gli elementi
    un nuovo riscontro con l'equals e a questo punto ricerchi nuovamente tutti i colori e selezioni solo il primo.

    sembra piuttosto contorta come operazione ed inoltre se due "tipo" possiedono colori differenti perdi il contenuto di uno.

    non so esattamente l'obbiettivo finale ma sembra esserci comunque qualcosa che non torna.
    perchè ammettendo che tutti i tipi dello stesso "tipo" hanno lo stesso colore, concettualmente c'è qualcosa di sbagliato nell'avere righe identiche nella stessa tabella del database.

    pertanto diciamo che lo scopo finale è raggruppare per ogni "tipo" tutta una serie di colori distinti e depositarli in un dizionario che come chiave abbia il "tipo" e come valore ha una collezione di colori.

    senza il dizionaro potresti fare
    codice:
                var grouped = Datas
                             .GroupBy(u => u.Tipo)
                             .Select(grp => grp.ToList()).ToList();
    
    // output
                for (int i = 0; i < grouped.Count; i++)
                    for (int j = 0; j < grouped.Count; j++)
                        Console.WriteLine(String.Format("{0} {1}", grouped[i][j].Tipo, grouped[i][j].Colore));
    grouped è una collezione che contiene a sua volta una serie di collezioni per ogni "tipo" differente
    nota bene che qui un elementi è sparito perchè essendoci un doppione di "tipo2" e "rosso" viene raggruppato (in questo caso).

    mentre per la parte con il dizionario e con tutti gli elementi puoi fare
    codice:
                Dictionary<string, List<Data>> grouped = Datas
                             .GroupBy(u => u.Tipo)
                             .ToDictionary(x => x.Key, x => x.ToList());
    
    // output
                foreach (var keypar in grouped)
                {
                    Console.WriteLine(keypar.Key);
                    foreach (var color in keypar.Value)
                        Console.WriteLine(color.Colore);
                }
    pertanto in Key possiedi il tipo attuale di raggruppamento, mentre in Value contieni i tuoi oggetti o elementi di colore associati al tipo.

    per quanto riguarda le prestazioni l'ultimo codice è quello che reagisce meglio, chiaramente tenendo conto che se nella tabella ci sono tipi uguali con colori uguali non vengon rimossi, pertanto potresti avre doppioni.

    però queste sono gestioni dal lato db il quale deve sempre essere in uno stato eccellente essendo la base dati dell'applicativo e dei futuri programme.

    pertanto per incrementarne la sicurezza di gestione ti converebbe creare una nuova tabella per "tipo" ed una per "colore" fornite di ID indicizzati come chiavi primarie cosi da evitare false scritture o problemi legati al case sensitive su stringhe, e conseguentemente alla duplicazione dei dati.
    Ultima modifica di Marsh; 03-08-2015 a 12:36

  5. #5
    Utente di HTML.it L'avatar di exFelino
    Registrato dal
    Jul 2014
    residenza
    Aci Catena (CT)
    Messaggi
    710
    Ciao,
    ma la situazione è un pò diversa, io ho un dataTable del genere:
    codice:
    ID      TIPO    COLORE
    1        C        ciano
    2        L        rosa
    3        L        rosa
    4        P        blu
    5        C        ciano
    6        D        rosso
    7        D        ross
    8        C        ciano
    9        P        blu
    10       L        rosa
    quindi eseguendo un distinct basata sul TIPO ricavo il colore appartenente al quel TIPO la cui associazione è univoca sin dall'inizio.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2015
    Messaggi
    57
    non capisco il senso della tabella, è concettualmente errata, perchè possedere dati uguali su righe diverse?
    possiede dati multipli ma che non hanno scopo, perchè comunque quando esegui il distinct andrà sempre sul primo elemento di quel tipo, che motivo ti porta a possedere cloni del genere?

    ammettendo che la tabella possiede altre colonne, che non sono cosi speculari comunque ti converebbe esportare I colori in una nuova tabella univoca e fare il riferimento sull'attuale tramite l'id.

    se mantieni le cose cosi allora ti basta andare sul primo elemento.
    codice:
     
               Dictionary<string, string> grouped = Datas
                 .GroupBy(u => u.Tipo)
                 .ToDictionary(x => x.Key, x => x.First().Colore);
                // output
                foreach (var keypar in grouped)
                    Console.WriteLine(keypar);
    però ripeto è sbagliata una tabella del genere, ricorda che il db deve essere un element solido e riutilizzabile, perchè se dovessi metterci le mani in futuro il cambio di qualcosa li ti porterebbe anche a grosse modifiche nel tuo applicativo.

    distinct e group by svolgono la medesima funzione, la differenza sostanziale è che group by ti permette di utilizzare funzioni aggregate mentre rimuove i duplicati, invece distinct rimuove unicamente i doppioni
    Ultima modifica di Marsh; 03-08-2015 a 13:50

  7. #7
    Utente di HTML.it L'avatar di exFelino
    Registrato dal
    Jul 2014
    residenza
    Aci Catena (CT)
    Messaggi
    710
    Esatto, la tabella contiene altri elementi, forse un GroupBy permette di semplificare il codice di selezione.

    Lo terrò in mente per la prossima volta.

    Grazie.

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.