Come posso convertire IEnumerable<T> in List<T> in C#?
Domanda
Sto utilizzando LINQ per interrogare un dizionario generico e quindi utilizzare il risultato come origine dati per il mio ListView (WebForms).
Codice semplificato:
Dictionary<Guid, Record> dict = GetAllRecords();
myListView.DataSource = dict.Values.Where(rec => rec.Name == "foo");
myListView.DataBind();
Pensavo che avrebbe funzionato, ma in realtà genera a System.InvalidOperationException:
ListView con ID 'MyListView' deve avere un'origine dati che implementa ICollection o può eseguire il paging dell'origine dati se l'incontro è vero.
Per farlo funzionare ho dovuto ricorrere a quanto segue:
Dictionary<Guid, Record> dict = GetAllRecords();
List<Record> searchResults = new List<Record>();
var matches = dict.Values.Where(rec => rec.Name == "foo");
foreach (Record rec in matches)
searchResults.Add(rec);
myListView.DataSource = searchResults;
myListView.DataBind();
C'è un piccolo trucco nel primo esempio per farlo funzionare?
(Non ero sicuro di cosa usare come titolo della domanda per questa domanda, sentiti libero di modificarlo con qualcosa di più appropriato)
Soluzione
Prova questo:
var matches = dict.Values.Where(rec => rec.Name == "foo").ToList();
Tieni presente che ciò essenzialmente creerà un nuovo elenco dalla raccolta Values originale, pertanto eventuali modifiche al dizionario non si rifletteranno automaticamente nel controllo associato.
Altri suggerimenti
Tendo a preferire l'utilizzo della nuova sintassi Linq:
myListView.DataSource = (
from rec in GetAllRecords().Values
where rec.Name == "foo"
select rec ).ToList();
myListView.DataBind();
Perché prendi un dizionario se non usi la chiave?Stai pagando per quelle spese generali.
Potresti anche provare:
var matches = new List<Record>(dict.Values.Where(rec => rec.Name == "foo"));
Fondamentalmente le raccolte generiche sono molto difficili da lanciare direttamente, quindi non hai altra scelta che creare un nuovo oggetto.
myListView.DataSource = (List<Record>) dict.Values.Where(rec => rec.Name == "foo");
Il solo fatto di aggiungere conoscenza alla frase successiva non recupera alcun dato da de db.Basta creare solo la query (per questo è di tipo interrogabile).Per avviare questa query è necessario aggiungere .ToList() o .First() alla fine.
dict.Values.Where(rec => rec.Name == "foo")