C# ';无法完成该操作,因为DbContext已被释放;

C# ';无法完成该操作,因为DbContext已被释放;,c#,.net,asp.net-mvc,C#,.net,Asp.net Mvc,我不明白为什么会发生这个错误。我添加了一个搜索框来搜索数据库。我还添加了一个勾选框来显示未付款的客户。当我改变 public ActionResult Index(FormModel form) { using (DBModels db = new DBModels()) { var clients = from c in db.Clients select c; if (!String.IsNull

我不明白为什么会发生这个错误。我添加了一个搜索框来搜索数据库。我还添加了一个勾选框来显示未付款的客户。当我改变

public ActionResult Index(FormModel form)
{
    using (DBModels db = new DBModels())

    {
        var clients = from c in db.Clients
                      select c;

        if (!String.IsNullOrEmpty(form.SearchString))
        {
            clients = clients.Where(s => s.Full_Name.Contains(form.SearchString) || s.Class.Contains(form.SearchString)
            || s.Membership_Type.Contains(form.SearchString) || s.Membership_Type.Contains(form.SearchString) ||
            s.Notes.Contains(form.SearchString) || s.ClientID.Equals(form.SearchString));
        }
             if (form.IsChecked != null)
              {
                  clients = clients.Where(t => t.Paid == form.IsChecked);
              }
        return View(clients);

    }
}  
回到

return View(clients); 

它可以工作,但这正是我试图避免的,因为它显示了所有列表,而不是“clients”变量,该变量显示了搜索字符串中的内容。

clients
是一个IQueryable。在请求第一次迭代之前,IQueryable不会枚举它的值。此时,您的DbContext已经被释放,因此枚举抛出一个异常

要解决这个问题,请使用以下方法

使用(DBModels db=new DBModels())
{
var clients=Enumerable.Empty();
如果(!String.IsNullOrEmpty(form.SearchString))
{
clients=db.clients.Where(s=>s.Full_Name.Contains(form.SearchString)| | s.Class.Contains(form.SearchString)
||s.Membership_Type.Contains(form.SearchString)| s.Membership_Type.Contains(form.SearchString)||
s、 Notes.Contains(form.SearchString)| | s.ClientID.Equals(form.SearchString));
}
if(form.IsChecked!=null)
{
clients=clients.Where(t=>t.Paid==form.IsChecked);
}
返回视图(clients.ToList());
}
理论上,在调用ToList()之前应该避免数据库调用,但我已经有一段时间没有这样做了。相反,我建议使用LinqKit构建一个完全针对数据库运行的查询,如下所示:

使用(DBModels db=new DBModels())
{
var predicate=PredicateBuilder.New(true);
如果(!String.IsNullOrEmpty(form.SearchString))
{
谓词.And(s=>s.Full_Name.Contains(form.SearchString)| | s.Class.Contains(form.SearchString)
||s.Membership_Type.Contains(form.SearchString)| s.Membership_Type.Contains(form.SearchString)||
s、 Notes.Contains(form.SearchString)| | s.ClientID.Equals(form.SearchString));
}
if(form.IsChecked!=null)
{
谓词和(t=>t.Paid==form.IsChecked);
}
返回视图(db.Clients.Where(谓词).ToList());
}

IQueryable类型的数据结构主要用于迭代,在使用ToList之前,它们不会产生价值。
这就是为什么在释放dbcontext后不会对对象求值的原因。

请提供一个警告,说明当视图试图访问列表时,DBModel已被释放,因此会发生错误。您可以通过多种方式解决此问题。或者通过更改db变量的生存时间。。。使其成为成员,或者您可以更改控制器和视图,以将所需参数传递到控制器中的过滤器。如果不知道视图中发生了什么,就很难给出答案
return View(db.Client.ToList());