2009-06-05 11 views
248

Voglio aggiungere alcune righe a un database utilizzando Linq a SQL, ma voglio fare un "controllo personalizzato" prima di aggiungere le righe per sapere se devo aggiungere, sostituire o ignorare le righe in entrata . Mi piacerebbe mantenere il trafic tra il client e il server DB il più basso possibile e ridurre al minimo il numero di query.Convertire Linq Query Result al dizionario

Per fare ciò, desidero recuperare le informazioni minime richieste per la convalida e solo una volta all'inizio del processo.

Stavo pensando di fare qualcosa del genere, ma ovviamente, non funziona. Qualcuno ha un'idea?

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj 
     select (new KeyValuePair<int, DateTime>(ot.Key, ot.TimeStamp)) 
    ) 

Quello che mi piacerebbe avere, alla fine sarebbe un dizionario, senza dover scaricare l'intero oggetti ObjectType da TableObject.

Ho anche considerato il seguente codice, ma stavo cercando di trovare un modo corretto:

List<int> keys = (from ObjType ot in TableObj orderby ot.Key select ot.Key).ToList<int>(); 
List<DateTime> values = (from ObjType ot in TableObj orderby ot.Key select ot.Value).ToList<int>(); 
Dictionary<int, DateTime> existingItems = new Dictionary<int, DateTime>(keys.Count); 
for (int i = 0; i < keys.Count; i++) 
{ 
    existingItems.Add(keys[i], values[i]); 
} 

risposta

467

Provare a utilizzare the ToDictionary method in questo modo:

var dict = TableObj.Select(t => new { t.Key, t.TimeStamp }) 
        .ToDictionary(t => t.Key, t => t.TimeStamp); 
+1

Cos'è T qui ??? – PawanS

+1

@pawan, è un segnaposto per ogni elemento nell'enumerazione e assume il tipo di oggetti nell'enumerazione. – tvanfosson

+0

@ tvanfosson puoi spiegarmi una cosa. Non sono in grado di capire. Ora il mio compito è di convertire un linq in dizionario. Problema è Il valore è una stringa (creazione in LINQ) formato e la chiave è p "" "var serverUrl = (dalla lista p in [i] .ProjectName select {(" tcp: // "+ lista [i] .BuildMachineName +" : "+ lista [i] .PortNumber +" /CruiseManager.rem ", p)}" "" – PawanS

7

Provate il seguente

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj).ToDictionary(x => x.Key); 

o il tipo a tutti gli effetti la versione inferenced

var existingItems = TableObj.ToDictionary(x => x.Key); 
+0

Grazie per l'anwser JaredPar. Ho insegnato qualcosa del genere, ma penso che questo restituisca l'intero oggetto del tipo ObjType, e voglio evitare di dover scaricare tutti gli oggetti. – Tipx

+0

@Tipx, puoi fornire alcune informazioni su cosa vuoi filtrare? L'aggiunta di una clausola di filtro è possibile, ma non posso dire dalla tua domanda cosa è importante – JaredPar

+0

Tutto quello che devo sapere se la "nuova riga" deve essere aggiunta, essere ignorata o sostituire un'altra riga è il timestamp dell'oggetto. Gli oggetti nel DB hanno un sacco di campi che non ho bisogno per la convalida e non voglio ottenere il colpo di prestazioni di ottenere gli oggetti interi. Per semplificare, ho ottenuto un tavolo nel mio BD con 20 colonne, 100.000 righe e vorrei estrarre un dizionario usando i valori delle prime 2 colonne. – Tipx

96

Guardando il tuo esempio, penso che questo sia quello che desideri:

var dict = TableObj.ToDictionary(t => t.Key, t=> t.TimeStamp); 
+0

Wow ... Potrebbe essere semplice ...Dato che sono abbastanza nuovo alla programmazione, cercherò di farlo e fare un po 'di profilazione per assicurarmi che sotto il cofano non ottenga il colpo dell'intero oggetto. Vi terrò aggiornati. – Tipx

+0

Ho appena fatto il mio assegno. Tristemente, mentre ricevo il TableObj, recupera tutti gli oggetti dal db così finisco col ricevere il colpo del traffico. Ho anche controllato le query sul secondo modo che ho postato (e volevo evitare) e hanno solo gli elementi necessari. Certo fa 2 query in modo che il server stesso debba cercare due volte le tabelle, ma la mappatura degli oggetti è abbastanza semplice. – Tipx

+6

Potrebbe essere possibile: TableObj.Select (t => new {t.Key, t.TimeStamp}). ToDictionary (t => t.Key, t => t.TimeStamp); LinqToSql dovrebbe essere in grado di notare che vuoi solo due cose (dalla selezione) e restituirle. Non sono sicuro che sia abbastanza intelligente da scavare nelle specifiche di ToDictionary(). – Talljoe

0

use namespace

using System.Collections.Specialized; 

Fai istanza della classe DataContext

LinqToSqlDataContext dc = new LinqToSqlDataContext(); 

Usa

OrderedDictionary dict = dc.TableName.ToDictionary(d => d.key, d => d.value); 

Al fine di recuperare i valori d'uso dello spazio dei nomi

using System.Collections; 

ICollection keyCollections = dict.Keys; 
ICOllection valueCollections = dict.Values; 

String[] myKeys = new String[dict.Count]; 
String[] myValues = new String[dict.Count]; 

keyCollections.CopyTo(myKeys,0); 
valueCollections.CopyTo(myValues,0); 

for(int i=0; i<dict.Count; i++) 
{ 
Console.WriteLine("Key: " + myKeys[i] + "Value: " + myValues[i]); 
} 
Console.ReadKey();