2010-07-30 7 views
10

Estoy buscando reglas generales para llamar a ToList/ToArray/MemoizeAll(Rx) en IEnumerables, en lugar de devolver la consulta al devolver IEnumerable de algo.Reglas generales para cuando llamar a ToList al devolver los resultados de LINQ

A menudo encuentro que es mejor simplemente devolver la consulta y dejar que la persona que llama decida si una lista es necesaria o no, pero a veces puede regresar y morder en la parte posterior debido a la naturaleza perezosa de linq.

Quiero recoger directrices tales como:

ToList llamada si:

  • que crear nuevos objetos
  • usted tiene efectos secundarios de la consulta
  • (por ejemplo, en un grupo selecto.)

De lo contrario, devuelva la consulta

+4

Rara vez (¿nunca?) Deberías tener efectos secundarios en tu consulta. –

Respuesta

23

En primer lugar, NUNCA debe tener efectos secundarios en una consulta. Esa es una peor práctica. Las consultas deben responder una pregunta, no producir un efecto.

La respuesta a su pregunta es: devolver una consulta cuando la persona que llama espera una consulta; devolver una lista cuando la persona que llama espera una lista. Cuando diseñe su método, decida qué es más probable que desee la persona que llama, impleméntelo y luego documento.

Al considerar si la persona que llama desea una consulta o una lista, piensan acerca de las diferencias entre consultas y listas:

  • consultas están siempre actualizados. Si los objetos/bases de datos/lo que sea que consulta la consulta cambian su contenido, los resultados de la consulta cambiarán si ejecuta la consulta nuevamente. Las listas no cambian su contenido y, por lo tanto, las listas se vuelven obsoletas. Si su interlocutor necesita , los últimos datos, luego de darles una consulta. Si requieren una instantánea de los datos que pueden inspeccionar en el ocio, proporcióneles una lista.

  • consultas son potencialmente costosas de ejecutar para obtener sus resultados. Las listas son baratas para obtener sus resultados. Si la persona que llama es probable que quiera interrogar el resultado muchas veces y espera obtener los mismos resultados cada vez, entonces déles una lista.

  • La construcción de una consulta es rápida. La ejecución de una consulta para construir una lista es lenta. Una lista siempre obtiene todos los resultados de una consulta. La persona que llama puede querer restringir aún más la consulta, por ejemplo, tomando solo los primeros diez elementos. Si la persona que llama no quiere o no necesita asumir el costo de iterar por completo sobre toda la consulta, entonces déle una consulta; no tomes esa decisión en su nombre y dales una lista.

  • las consultas son tiny. Las listas son grande. Muchas consultas se pueden repetir en n elementos en el espacio O (1); una lista con n elementos ocupa O (n) espacio. Si el conjunto de resultados es enorme, ponerlo en una lista probablemente sea ineficiente.

  • y así sucesivamente.

No hay una respuesta fácil. La respuesta es la misma que la respuesta a cualquier otro problema de diseño: Tenga en cuenta todos los pros y los contras de cada solución posible en el contexto de lo que probablemente el usuario desee de la función, y luego elija una solución de compromiso razonable.

3

Volver ToList si:

  • Usted no quiere o cuidar de evaluación de consultas perezoso.

Editar:

Además, el retorno ToList si:

  • Está utilizando algún tipo de LINQ to SQL marco (LLBLGen, EF, etc.), y que tiene que hacer una operación en la lista que el marco no puede traducir a SQL.
+0

+1 para la edición. Especialmente si las operaciones subsecuentes causarían que la base de datos sea atacada varias veces por la misma consulta. Utilice el perfilador del servidor SQL para determinar dónde usar 'ToList()'. – Necros

1

ToList() cuando desea una lista de objetos para su resultado.

+0

+1: No creo que pueda ser mejor que esto como una guía general. –

+0

@Lasse: Sí. Esta respuesta no explica * cuando * quisiéramos una 'Lista '. –

+1

Porque hay un millón de casos de uso en los que desea utilizar una 'Lista ' y un millón de casos de uso (que se ven extrañamente iguales) donde no desea usarlos. Es completamente específico para el escenario en cuestión. ¿Cuál es la pauta para cuándo usar una variable? ¿Cuál es la guía para cuándo usar una cadena? Realmente no puedes crear una guía que así lo diga. Ahora, estoy de acuerdo, puedes describir las características de una lista y luego decir "cuando necesites algo de esto, quieres usar una lista", pero él está pidiendo pautas para * devolver datos *. No puede, porque si quiere usar una lista o no, no depende de usted. –

2

Utilice ToList si necesita ejecutar funciones personalizadas en los datos devueltos por LINQ to SQL.

2

Use ToList antes de salir del bloque using que contiene su DataContext.

Devuelva una consulta cuando la persona que llama probablemente/tenga la obligación de proporcionar criterios de filtrado adicionales que serán utilizados por los índices para reducir el nº de filas de resultado y/o IO de la base de datos.

Cuestiones relacionadas