【问题标题】:how to reattach the IQueryable object to a new instance of Context object如何将 IQueryable 对象重新附加到 Context 对象的新实例
【发布时间】:2013-08-14 03:03:34
【问题描述】:

我想将最后搜索的查询保存在一个全局变量中,当我在另一个方法中使用它时,它会说:

ObjectDisposedException 未被用户代码处理:ObjectContext 实例已被释放,不能再用于需要连接的操作。

IQueryable lastQry = null;

private void SearchMethod()
{
   using(var ctx = new entityContex())
   {
      var qry = ctx.Table1.Where(t=> t.Name.StartWith(txtName.Text)).Take(100);

      lastQry = qry;

      dgvResult.DataSource = qry.ToList();
   }
}

private void RefreshResult()
{
   using(var ctx = new entityContex())
   {
      if(lastQry != null)
      //here is the Error ! <<---------------->>
      dgvResult.DataSource = lastQry.ToList();
   }
}

【问题讨论】:

  • 您使用的是什么类型的上下文(DbContextObjectContext)?
  • 它的对象上下文,我使用的是EF 6.0数据库第一模型
  • 您是要存储上一个查询的结果,还是存储查询本身以便再次执行?

标签: c# entity-framework entity-framework-4 linq-to-entities


【解决方案1】:

一种方法是创建并存储一个运行查询的委托:

Func<entityContex, IQueryable</*Table1 type*/>> queryExecutor = null;

private void SearchMethod()
{
   using(var ctx = new entityContex())
   {
      queryExecutor = c => c.Table1.Where(t=> t.Name.StartWith(txtName.Text)).Take(100);

      var qry = queryExecutor(ctx);

      dgvResult.DataSource = qry.ToList();
   }
}

private void RefreshResult()
{
   using(var ctx = new entityContex())
   {
      if(queryExecutor != null)
      dgvResult.DataSource = queryExecutor(ctx).ToList();
   }
}

【讨论】:

  • queryExecuter Func 只是保留上下文的实例,不让它释放,是吗?
  • @patachi: 不,queryExecutor 接受上下文作为参数,然后针对该上下文调用查询。 Func 中捕获的唯一内容是创建 Func 实例时的值 txtName.Text
  • 真的!这意味着 ctx 带到 RAM 的所有表记录都将以这种方式处理,我在将 entityContex 的实例定义为类的静态成员时遇到了一些问题:D
  • @patachi,是的,上下文将按预期处置,处置后不会被 Func 重用。
【解决方案2】:

而不是存储IQueryable,存储列表:

List<Table1> lastQry = null;

private void SearchMethod()
{
 using(var ctx = new entityContex())
 {
   var qry = 
     ctx.Table1
       .Where(t=> t.Name.StartWith(txtName.Text))
       .Take(100)
       .ToList(); // <--

   lastQry = qry;
   dgvResult.DataSource = qry;
 }
}

private void RefreshResult()
{
  using(var ctx = new entityContex())
  {
    if(lastQry != null)
      dgvResult.DataSource = lastQry;
  }
}

【讨论】:

  • 如果最后一个查询返回大量数据,并且到下一个查询的时间很长,这可能会导致内存使用率很高
  • @boindiil:由于.Take(100),它不会返回大量数据。
  • tnx 但是,我们有几个用户在处理搜索的项目并同时对这些项目进行某种删除、编辑、...,我们需要过滤的搜索结果应该达到日期,我通过使用上下文的静态实例来解决问题,但我喜欢更好的方法;D
猜你喜欢
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多