EF6 alpha异步等待实体存储过程/函数导入?

blu*_*ish 5 entity-framework async-await c#-5.0 entity-framework-6

我想将新的异步等待功能应用于我的实体模型中导入的存储过程/函数导入,但目前还无法使用EF6 alpha.

在EF6 alpha2(或20211的每晚构建)中,是否可以在实体函数导入(调用SQL存储过程)上调用任何返回复杂类型集合的新Async方法?例如

private async Task<IList<Company>> getInfo (string id)
{
    using (CustomEntity context = new CustomEntity())
    {
        var query = await context.customStoredProcedure(id).ToListAsync();
        // ".ToListAsync()" method not available on above line

        // OR ALTERNATIVELY
        var query = await (from c in context.customStoredProcedure(id)
                           select new Company
                           {
                              Ident = c.id,
                              Name = c.name,
                              Country = c.country,
                              Sector = c.sector, 
                              etc. etc....
                           }).ToListAsync();
        // ".ToListAsync()" method or any "...Async" methods also not available this way

        return query;
    }
}
Run Code Online (Sandbox Code Playgroud)

"ToListAsync"或任何新的异步修改方法似乎不可用于上述实体存储过程/函数导入; 只有标准的"ToList"或"AsNumerable"等方法可用.

我遵循这个(http://entityframework.codeplex.com/wikipage?title=Updating%20Applications%20to%20use%20EF6)以确保代码引用新的EF6 dll而不是EF5,以及更新各种使用声明.除此之外,一切都正确建立.(.NET Framework 4.5)

我唯一能看到异步方法的是,如果不是仅从DB导入存储过程,我还导入一个表 - 然后在通过上面的Entity上下文引用该表时(context.SomeTable),一些异步方法出现在intellisense中.

在将数据作为JSON返回之前,我真的想在多个存储过程中开始使用新的异步等待功能,但到目前为止还无法使其工作.

难道我做错了什么?实体存储过程/函数导入是否无法实现异步功能?谢谢你的建议.

Jer*_*emy 3

现在这绝不是最好的解决方案。我添加了一个扩展方法,以便我可以在存储过程上调用await。在 EF6.1+ 的新版本中,我们应该会看到这一点被正式实现。在那之前,虚拟扩展方法会完成这项工作。

static async Task<List<T>> ToListAsync<T>(this ObjectResult<T> source)
{
    var list = new List<T>();
    await Task.Run(() => list.AddRange(source.ToList()));
    return list;
}
Run Code Online (Sandbox Code Playgroud)

如果您反映 EF 版本 6,您将看到它ObjectResult<T>实际上实现了IDbAsyncEnumerable<T>, IDbAsyncEnumerable. 并且 for 的方法ToListAsync<T>(this IDbAsyncEnumerable<T> source)应该能够像 LINQ 查询一样连接它。

编辑 当ObjectResult为空时返回null。if (source == null) return new List<T>();如果你想返回一个空列表而不是 null,你可以添加。

  • 使用“Task.Run”生成一个新线程只是为了“等待”一个方法,这完全违背了 async/await 的目的。您通过等待释放了主线程,但随后您刚刚生成了一个新线程。当您考虑生成这个新线程的开销,然后在您生成的线程完成时最终在主线程上恢复时,您的性能实际上会更差。 (6认同)