2012-05-10 22 views
6

Tengo una tabla que tiene una clave de 2 partes; una columna de ID y un número de versión. Intento seleccionar "solo la última versión" de los registros.¿Por qué no es este grupo LINQ al agregar las filas en vb.net?

Estoy tratando de usar el estilo de expresión de LINQ, para lograr un GROUP BY, y extraer el valor MAX total de la Versión. Sin embargo, no se produce ninguna agregación.

Código Resumido:

From C In Credentials 

Group Join .... 
Group Join .... 

Group C.CredentialID, NE.ClientID, C.Version By 
    NE.ClientID, C.CredentialID Into CGroup = Group 
From CG In CGroup 

Select New With { 
    .ClientID = CG.ClientID, 
    .CredentialID = CG.CredentialID, 
    .MaxVersion = CGroup.Max(Function(p) p.Version) 
} 

Resultados reales:

ClientID CredentialID MaxVersion 
1196  1   3 
1196  1   3 
1196  1   3 
1196  2   1 

resultados deseados:

ClientID CredentialID MaxVersion 
1196  1   3 
1196  2   1 

, también trató mismos resultados:

Group C By Key = New With 
    {Key NE.ClientID, Key C.CredentialID} Into CGroup = Group 
From CG In CGroup 

Select New With { 
    .ClientID = Key.ClientID, 
    .CredentialID = Key.CredentialID, 
    .MaxVersion = CGroup.Max(Function(p) p.Version) 
} 

estoy en busca de una solución que no implica la creación de clases personalizadas con propiedades que corresponden a la clasificación y agrupación de encargo/funciones, y no utiliza las expresiones lambda en el extremo de la cola de la consulta.

Gracias!

Respuesta

3
From CG In CGroup 

Esta línea llama Queryable.SelectMany y descomprime los grupos. ¡No desempaque sus grupos!

Eliminar esa línea y terminar con:

Select New With { 
    .ClientID = CGroup.Key.ClientID, 
    .CredentialID = CGroup.Key.CredentialID, 
    .MaxVersion = CGroup.Max(Function(p) p.Version) 
} 
+0

guau, forma de salvar el día –

+0

¿Puedo preguntar dónde aprendió esta importante pepita de información? –

+0

Principalmente de verter sobre las referencias msdn para System.Linq.Enumerable y System.Linq.Queryable. No tengas miedo de usar la sintaxis lambda, el compilador convierte lo que escribes en eso de todos modos. –

1

El problema es que la clase anónima definida para la clave no evalúa la igualdad de la manera que desee. En su lugar, puede utilizar una tupla de la clave:

From C In Credentials 
... 
Group C.CredentialID, NE.ClientID, C.Version By key = 
     New Tuple(Of Integer, Integer)(NE.ClientID, C.CredentialID) 
     Into CGroup = Group 
Select New With { 
     .ClientID = key.Item1, 
     .CredentialID = key.Item2, 
     .MaxVersion = CGroup.Max(Function(p) p.Version) 
} 
+0

Tengo este error en tiempo de ejecución y en LINQPad: "Solamente los constructores sin parámetros y inicializadores son compatibles en LINQ a Entidades". –

+0

Oh, acabo de probar con Linq2Objects. Me temo que, a menos que desee usar mal otras clases para ese caso, tendrá que crear una clase pequeña que pueda contener la tecla. –

+0

Linq a los objetos es irrelevante. Esta es una consulta EF. La consulta se envía a la base de datos y no se evalúa con instancias .net. No hay instancias de clave de grupo anónimas y su semántica de igualdad no se usa. –

Cuestiones relacionadas