2010-10-15 9 views
6

tengo un método, que devuelve un conjunto de cuentasTipo de retorno para la Recolección de LINQ consulta

Public Shared Function GetAllNotesByUser(ByVal UserID As Guid) As Account (??) 
    Using db As New MyEntity 
     Dim query= (From A In db.Account _ 
        Where A.aspnet_Users.UserId = UserID _ 
        Select A) 
     Return query 
    End Using 
End Function 

Después me gustaría que pasar esto a otra función para calcular los totales de todas las cuentas de la colección. ¿Es una buena práctica devolver una lista innumerable, genérica? No estoy seguro de qué funciona mejor con LINQ y con el marco de entidades.

Respuesta

7

Al propagar los resultados de la consulta LINQ de los métodos de esta manera, la mejor opción para el tipo de devolución es IEnumerable(Of T) para LINQ a objetos o IQueryable(Of T) para otros proveedores LINQ. En este caso, parece que Account es el tipo IEnumerable(Of Account) o IQueryable(Of T) según el tipo de consulta en cuestión.

+1

la mejor opción es 'IEnumerable' excepto cuando la mejor opción es' IQueryable'. ;) –

+0

@Kirk, cierto. Me olvidé de ese caso para consultas que no son LINQ to object – JaredPar

2

El mejor tipo sería

IEnumerable<Account> 

o la sintaxis correspounding en VB: P

En realidad, todas las funciones de LINQ (.Where(), .Distinct() etc) son los métodos de extensión a IEnumerable<T>, que creo que es es una buena práctica continuar la cadena de la misma manera.

+0

He buscado en MSDN, pero debo buscarlo en el lugar equivocado. ¿Cómo se sabe que WHERE() y Distinct() son métodos de extensión de IEnumerable . No te estoy interrogando, solo me pregunto dónde buscar la próxima vez que tenga una pregunta similar. –

+0

@Travis no hay problema. De hecho, en MSDN, no es realmente obvio "dónde" se definen esos métodos de extensión ... pero puede encontrar la lista en la página para 'IEnumerable ' (versión genérica): http://msdn.microsoft.com/ en-us/library/9eekhta0.aspx. Hay un ícono pequeño que dice que es un método de extensión ...y cuando hace clic en uno de ellos, puede ver en qué espacio de nombres vive ... Es decir, para usar cualquier método de extensión LINQ, debe tener 'using System.Linq;' en la parte superior de su archivo. – tsimbalar

+0

Ah, y la forma en que lo sabía, es simplemente porque VS siempre agrega una referencia a 'System.Linq' y el Intellisense simplemente los sugiere :-). En el capó, todas las expresiones de consulta tipo "linq" se convierten en cadenas de métodos de extensión de Linq. – tsimbalar

0

La pregunta que debe formular es: "¿Cuándo necesito que SQL se ejecute realmente?" En LINQ, es la diferencia entre la ejecución diferida y la inmediata. Cualquier método que devuelva IEnumerable<> tiene que ejecutar la consulta para obtener los resultados. IQueryable<>, por el contrario, retrasa la ejecución de la consulta hasta que se invoque un método que devuelve un IEnumerable<>. En el ejemplo que nos ha facilitado, puede ser más rápido para aprobar el resultado de la función GetAllNotesByUser como IQueryable<>, de modo que se ejecuta una sola consulta en lugar de dos:

public static IQueryable<Account> GetAllNotesByUser(Guid UserId) 
{ 
    ... 
} 

Puede haber situaciones en las que necesita para enumerar la resultado de GetAllNotesByUser sin realizar ninguna manipulación adicional. En esos casos, recuerde que puede llamar a 'ToList() `para forzar la ejecución de la consulta.

var result = GetAllNotesByUser(<guid>).ToList(); 
+0

'AsEnumerable' no fuerza la ejecución de la consulta: http://stackoverflow.com/questions/3389855/am-i-malentendido-linq-a-sql-asenumerable – nawfal

+0

Sí, tiene razón. ToList() forzará la ejecución. –

+0

Neil, luego edita tu respuesta. De lo contrario, garantiza un voto negativo :) – nawfal

1

Hay una buena respuesta en hereIEnumerable<T> vs IQueryable<T>.

Usaría IQueryable(Of T) si desea limitar aún más el conjunto en la persona que llama del método, por ejemplo con una cláusula WHERE. De lo contrario, usaría IEnumerable(Of T) si todas las personas que llaman saben que necesitan realizar una lista ToList() en el resultado si planean iterarlo más de una vez (de lo contrario, harían varias llamadas a la base de datos). Si las personas que llaman no están al tanto, probablemente usaría ICollection(Of T) y realizaría ToList() en el método mismo.