Как асинхронно вызывать базу данных с субрекциями с использованием LINQ?

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

Вопрос

Я использую EF6 и хочу сделать следующий запрос полностью асинхронным:

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

Это не работает, я считаю, из-за First() возвращения фактического объекта и доступа к ASubCollection являющегося ICollection , а не IQueryable .

Я смог обойти это со следующим кодом:

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

Однако это кажется «взломанным», поскольку я использую Where(...) когда я должен использовать First() как я знаю во время компиляции, что будет только один элемент, удовлетворяющий запросу. Есть ли лучший способ сделать это?

Принятый ответ

Вызов First() - это вызов, который фактически перечисляет базовую последовательность и возвращает объект вместо Task . Таким образом, First() не будет работать вместе с ключом await -keyword.

В этом контексте ваше второе решение полностью допустимо (а не «хакерское») в этом контексте, потому что нет необходимости добавлять ограничение к сгенерированному запросу базы данных, так как « Where(...) -call вернет ровно один элемент в этот специальный случай - с или без ограничения в запросе.

Если Where call, скорее всего, вернет несколько элементов, или вы просто хотите убедиться, что будет рассмотрен только первый элемент, вставка вызова Take(1) приведет к первому элементу последовательности, но все равно будет IQueryable :

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



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему