¿Cómo puedo convertir IEnumerable<T> a List<T> en C#?
Pregunta
Estoy usando LINQ para consultar un diccionario genérico y luego uso el resultado como fuente de datos para mi ListView (WebForms).
Código simplificado:
Dictionary<Guid, Record> dict = GetAllRecords();
myListView.DataSource = dict.Values.Where(rec => rec.Name == "foo");
myListView.DataBind();
Pensé que funcionaría pero en realidad arroja un System.InvalidOperationException:
ListView con ID 'myListView' debe tener una fuente de datos que implementa icollection o pueda realizar la paginación de origen de datos si ellowpaging es verdadero.
Para que funcione he tenido que recurrir a lo siguiente:
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();
¿Hay algún pequeño problema en el primer ejemplo para que funcione?
(No estaba seguro de qué usar como título de la pregunta para esta, siéntete libre de editarla a algo más apropiado)
Solución
Prueba esto:
var matches = dict.Values.Where(rec => rec.Name == "foo").ToList();
Tenga en cuenta que eso esencialmente creará una nueva lista a partir de la colección de Valores original, por lo que cualquier cambio en su diccionario no se reflejará automáticamente en su control vinculado.
Otros consejos
Tiendo a preferir usar la nueva sintaxis de Linq:
myListView.DataSource = (
from rec in GetAllRecords().Values
where rec.Name == "foo"
select rec ).ToList();
myListView.DataBind();
¿Por qué obtienes un diccionario si no usas la clave?Estás pagando por esos gastos generales.
También puedes intentar:
var matches = new List<Record>(dict.Values.Where(rec => rec.Name == "foo"));
Básicamente, las colecciones genéricas son muy difíciles de crear directamente, por lo que realmente no tienes más remedio que crear un nuevo objeto.
myListView.DataSource = (List<Record>) dict.Values.Where(rec => rec.Name == "foo");
Simplemente agregando conocimiento, la siguiente oración no recupera ningún dato de la base de datos.Simplemente cree la consulta (para eso es de tipo consultable).Para iniciar esta consulta debe agregar .ToList() o .First() al final.
dict.Values.Where(rec => rec.Name == "foo")