首页 > 解决方案 > 使用围绕 DB 上下文的 using 确定 LINQ 语句的范围

问题描述

我有一个返回查询结果以进行进一步过滤的函数,如下所示:

public IQueryable<MyData> Query(string name) {
  using (var dbc = new MyDbContext()) 
    return dbc.MyData.Where(v => v.Name == name);
}

然后我在另一个函数中调用它:

public f() { 
  var res = Query("john").Select(v => ......
  var resList = res.ToList();
  ...
}

MyDbContext在这种情况下的范围是什么?它什么时候处理?何时Query()返回或何时ToList()结束f()

如果是前者,我该如何更改它以便在ToList()完成时处理 DB 上下文?

(注意:我知道通常不需要在 EF 中使用 around DbContext,但我希望在这种情况下使用它,因为我正在尝试解决 sqlite 锁定问题)

谢谢!

标签: c#entity-frameworklinqentity-framework-6c#-7.0

解决方案


好吧,using从句只是一个try finally块。所以Query将转换为类似的东西:

public IQueryable<MyData> Query(string name) {
  MyDbContext dbc;

  dbc = new MyDbContext();
  try
  {

     return dbc.MyData.Where(v => v.Name == name);
  }
  finally
  {
     dbc.Dispose();
  }   
}

Query返回后IQueryable,上下文很可能会立即处理(甚至在调用之前.Select(v => ......)。

让调用者处理上下文有点“干净”。您可以在函数之外创建一个上下文对象Query并将其作为参数传递:

public IQueryable<MyData> Query(MyDbContext dbc, string name) {
     return dbc.MyData.Where(v => v.Name == name);
}

public f() { 
  using(var dbc = new MyDbContext())
  {
      var res = Query(dbc, "john").Select(v => ......
      var resList = res.ToList();
      ...
  }      
}

总体思路很简单,建议不要使事情过于复杂:

  1. 创建数据库上下文
  2. 做任何你需要做的事情
  3. 丢弃它

推荐阅读