如何使用LINQ异步调用带有子记录的数据库?

Ale*_*lex 9 linq datacontext async-await c#-5.0 entity-framework-6

我正在使用EF6,并希望使以下查询完全异步:

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

这不起作用,我相信由于First()返回实际的实体和访问ASubCollection是一个ICollection,而不是一个IQueryable.

我能够使用以下代码解决此问题:

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

然而,这似乎是"hacky",因为我正在使用一个Where(...)我应该使用的,First()因为我在编译时知道将只有一个元素满足查询.有没有更好的方法呢?

Spo*_*xus 7

调用First()是一个实际枚举基础序列并返回实体而不是a的调用Task.因此First()不能与await-keyword 一起使用.

在这种情况下,你的第二个解决方案是完全有效的(而不是"hacky"),因为没有必要为生成的数据库查询添加限制,因为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();
Run Code Online (Sandbox Code Playgroud)