sábado, 25 de junio de 2022

InvalidOperationException: Unable to translate collection subquery in projection since the parent query doesn't project key columns of all of it's tables which are required to generate results on client side. This can happen when trying to correlate on keyless entity or when using 'Distinct' or 'GroupBy' operations without projecting all of the key columns.

 Este problema es uno de los cambios más importantes en EF Core 5.0. Algunas consultas con colección correlacionada que también usan Distinct o GroupBy ya no son compatibles.

Ya no se admiten algunas consultas con colecciones correlacionadas que también usan Distinct o GroupBy

Comportamiento anterior

Anteriormente, las consultas que implicaban colecciones correlacionadas seguidas de GroupBy, así como algunas consultas con Distinct que permitimos ejecutar.

Ejemplo de GroupBy:

C#
context.Parents
    .Select(p => p.Children
        .GroupBy(c => c.School)
        .Select(g => g.Key))

Ejemplo de Distinct: en concreto, las consultas Distinct en las que la proyección de la colección interna no contiene la clave principal:

C#
context.Parents
    .Select(p => p.Children
        .Select(c => c.School)
        .Distinct())

Estas consultas podrían devolver resultados incorrectos si la colección interna contuviera duplicados, pero funcionaría correctamente si todos los elementos de la colección interna fueran únicos.

Comportamiento nuevo

Estas consultas ya no son compatibles. Se produce una excepción que indica que no hay suficiente información para compilar los resultados correctamente.

Por qué

En el caso de los escenarios de colecciones correlacionadas, es necesario conocer la clave principal de la entidad para asignar entidades de colección al elemento primario correcto. Cuando la colección interna no utiliza GroupBy ni Distinct, la clave principal que falta se puede agregar simplemente a la proyección. Sin embargo, en el caso de GroupBy y Distinct, no se puede hacer porque cambiaría el resultado de la operación GroupBy o Distinct.

Mitigaciones

Vuelva a escribir la consulta para que no use las operaciones GroupBy o Distinct en la colección interna y, en su lugar, realice estas operaciones en el cliente.

C#
context.Parents
    .Select(p => p.Children.Select(c => c.School))
    .ToList()
    .Select(x => x.GroupBy(c => c).Select(g => g.Key))
C#
context.Parents
    .Select(p => p.Children.Select(c => c.School))
    .ToList()
    .Select(x => x.Distinct())

No hay comentarios:

Publicar un comentario

Comenta cualquier duda o recomendatorio.