【问题标题】:Asynchronous method with context dispose具有上下文处理的异步方法
【发布时间】:2017-12-16 07:16:21
【问题描述】:

我有以下代码:

public Task<Service> GetSomething()
{
    using (var myContext = new DbContext())
    {
        var returnObj = (from rp in myContext.Services1
                        join op in myContext.Services2 on rp .Id equals op.ServiceId into g
                        join ep in myContext.Services3 on rp .Id equals ep.ServiceId
                        from n in g.DefaultIfEmpty()
                        where rp.Name == code
                        select rp).FirstOrDefaultAsync();

        return returnObj;
    }
}

现在这正在工作,但我遇到了错误:

The operation cannot be completed because the DbContext has been disposed.

阅读后,看起来FirstOrDefaultAsync 是一个延迟执行,我需要先将其转换为list 以使其具体化。

我将如何转换此查询的结果,因为我尝试了.ToListAsync(),但它之后没有任何FirstOrDefault

【问题讨论】:

  • 哪一行抛出异常?您是否启用了延迟加载?如果您进行了@Yeldar Kurmangaliyev 建议的更改并且仍然得到处理异常,那么我只能认为延迟加载是原因。

标签: c# entity-framework asynchronous


【解决方案1】:

在您的情况下,将调用 EF6 Async 操作并将其任务返回给原始调用者。然后,DbContext 立即被释放,无需等待完成。
这是对async/await 功能的错误使用。

您需要在处理上下文之前等待结果:

public async Task<YourEntity> GetYourEntity()
{
  using (var myContext = new DbContext())
  {
    var returnObj = (from rp in myContext.Services1
                     join op in myContext.Services2 on rp .Id equals op.ServiceId into g
                     join ep in myContext.Services3 on rp .Id equals ep.ServiceId
                     from n in g.DefaultIfEmpty()
                     where rp.Name == code
                     select rp).FirstOrDefaultAsync();

    //return returnObj; // returns Task, wrong!
    return await returnObj; // returns result, right!
  }
}

这样,它会等待操作完成,然后处理myContext

【讨论】:

  • 将你的方法标记为异步,就像public async Task&lt;Service&gt; GetSomething()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2014-04-02
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
相关资源
最近更新 更多