【问题标题】:Determining the scope of LINQ statement with a using around the DB context使用围绕 DB 上下文的 using 确定 LINQ 语句的范围
【发布时间】:2018-12-05 22:58:49
【问题描述】:

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

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-framework linq entity-framework-6 c#-7.0


    【解决方案1】:

    好吧,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 =&gt; ...... 之前)。

    让调用者处理上下文有点“干净”。您可以在 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. 丢弃

    【讨论】:

      猜你喜欢
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2018-04-16
      • 2021-11-26
      • 1970-01-01
      • 2014-08-11
      相关资源
      最近更新 更多