2009-02-10 9 views
7

Sto cercando di fare quello che penso sia qualcosa di semplice, ma ho il sospetto che sia semplicemente troppo n00b per sapere che probabilmente sto facendo qualcosa di sbagliato. Ho una domanda di ritorno LINQ:Cercando di cambiare le proprietà di una collezione IQueryable

IQueryable<CWords> Result 

Dove CWords è una classe ho definito come segue:

public class CWords 
{ 
    public CWords(){} 
    public string _column1{ get; set; } 
    public float _column2{ get; set; } 

    public void fixData(){} 
} 

nel mio codice, sto cercando di modidy campo _column2 per ogni membro del risultato. Ho provato:

foreach (CWords item in Result) 
{ 
    item.fixData(); 
} 

Ma ovviamente non ha funzionato. l'elemento non è nell'ambito appropriato, quindi le eventuali modifiche apportate a fixData non includevano Result.

bcause non è possibile indicizzare IQueryable, la mia correzione per questo è stato quello di effettuare le seguenti operazioni:

var items = goodWords.ToList(); 

for (int i = 0; i < items.Count(); i++) 
    { 
    items[i].fixData(); 
    } 

è che il modo giusto per fare questo?

risposta

13

Brandon, questo è un errore normale quando si utilizza LINQ. Vedi, l'IQueryable restituito da LINQ in realtà non contiene i tuoi articoli, ecco perché non puoi indicizzarlo. Ha solo le informazioni sufficienti per eseguire la query quando effettivamente chiedi gli articoli. Questo è chiamato "deferred execution", perché la query non viene eseguita quando si select, ma in seguito, quando si enumerano i risultati. È possibile cercare "linq esecuzione differita" e trovare molte persone che cercano di spiegare come funziona.

Quando si esegue la foreach, la query viene eseguita e si chiama fixData() su ciascun elemento, proprio come previsto. Tuttavia, quando accedi nuovamente a IQueryable, eseguirai la query una seconda volta e (a seconda del provider LINQ che stai utilizzando) potresti inserire gli elementi non modificati originali una seconda volta.

Chiamando ToList() su IQueryable, si crea un elenco in memoria con tutti i risultati della query. È ora possibile indicizzare in questo elenco e accedere a tutto ciò che si desidera senza eseguire nuovamente la query. Se stai bene con tutti gli elementi in memoria (un piccolo set di risultati), allora usare ToList() può essere una buona soluzione per te.

@PaulG, hai ragione che può utilizzare foreach anziché for, ma deve salvare un riferimento all'elenco oppure è proprio dove ha iniziato (con un IQueryable).

var items = goodWords.ToList(); 

foreach (var item in items) 
{ 
    item.fixData(); 
} 
0

Credo che il tuo buon parole è IQueryable<CWords> tipo?

Quindi perché non piace questo?

foreach (CWords item in goodWords.ToList()) 
{ 
    item.fixData(); 
} 
Problemi correlati