¿Cómo llamar de forma asíncrona a una base de datos con subregistros utilizando LINQ?

async-await c#-5.0 datacontext entity-framework-6 linq

Pregunta

Estoy usando EF6 y quiero hacer la siguiente consulta totalmente asíncrona:

 await MyDataContext.ADbSet.
                     First(a => a.Something == "Something").
                     ASubCollection.
                     Select(x => new { x.SubCollectionId }).
                     ToListAsync();

Esto no funciona, creo que debido al First() devolver la entidad real y el acceso a ASubCollection ser un ICollection , no un IQueryable .

Pude evitar esto con el siguiente código:

 await MyDataContext.ADbSet.
                     First(a => a.Something == "Something").
                     ASubCollection.
                     Select(x => new { x.SubCollectionId }).
                     ToListAsync();

Sin embargo, esto parece "hacky", ya que estoy usando un Where(...) cuando debería estar usando un First() ya que sé en el momento de la compilación que habrá exactamente un elemento que satisfaga la consulta. ¿Hay una mejor manera de hacer esto?

Respuesta aceptada

La llamada a First() es una llamada que en realidad enumera la secuencia subyacente y devuelve una entidad en lugar de una Task . Por lo tanto First() no funcionará junto con el await -palabra clave.

Su segunda solución es completamente válida (y no "hacky" en absoluto) en este contexto, porque no hay necesidad de agregar un límite a la consulta de base de datos generada, ya que la llamada Where(...) devolverá exactamente un elemento en este caso especial - con o sin límite en la consulta.

Si es probable que Where -call devuelva varios elementos, o simplemente desea asegurarse de que solo se considerará el primer elemento, al insertar una llamada a Take(1) obtendrá el primer elemento de la secuencia, pero seguirá siendo un IQueryable :

await MyDataContext.ADbSet
                   .Where(a => a.Something == "Something")
                   .Take(1)
                   .SelectMany(a => a.ASubCollection)
                   .Select(x => new { x.SubCollectionId })
                   .ToListAsync();



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué