在结果

时间:2016-03-07 15:39:28

标签: c# entity-framework asynchronous

我正在尝试创建一个异步方法,我可以多次调用并等待以后 - 该方法应该进行数据库调用,等待结果,一旦有结果就做一些操作,然后返回最终结果。它看起来像这样:

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer()
{
        //stuff is just an Entity Framework database call 
        var stuff = await myEfDbContext.StuffTable.ToListAsync();                     
        long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count();
        return itemsCount; 
}

这似乎是一个明显的错误,因为我将返回类型指定为Task,而实际上我只返回了很长时间。这会编译,但抛出异常:

  

“System.NotSupportedException”类型的第一次机会异常   发生在EntityFramework.dll

我打算像这样使用这段代码:

Task<long> myAsyncCall = GetSomethingFromDbAndSelectSomethingOnServer();
long myCount = await myAsyncCall;

这可能有点无关紧要,但是为了详细说明,这里有一些好处:

Task<long> pendingItemCountCall =  _mongoItems.Find(filter).CountAsync();
long myCount2 = await pendingItemCountCall;

当然,区别在于它只是对db的异步调用,没有进一步的操作,我正在SQL调用中尝试做我正在问的问题。

编辑:

所以,实际上,这似乎是违规行:

var stuff = await myEfDbContext.StuffTable.ToListAsync();  

如果我对此进行评论并手动设置计数var,那么代码就会出现。我很困惑,但我对整体问题更感兴趣 - 我是否在这里正确使用异步,不一定是我的特定错误的错误。

1 个答案:

答案 0 :(得分:3)

您无法在同一上下文中等待多个查询。您必须为每个操作使用自己的上下文:

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer()
{
        using(var context = new MyEfDbContext())
        {
            // include the following if you do not need lazy loading and want some more speed
            context.Configuration.AutoDetectChangesEnabled = false;
            context.Configuration.ProxyCreationEnabled = false;

            var stuff = await myEfDbContext.StuffTable.ToListAsync();                     
            long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count();
            return itemsCount;
        }
}