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


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); 

返回至

return View(db.Client.ToList()); 

它可以工作,但这是我试图避免的,因为它显示所有列表而不是显示来自 SearchString 的"客户端"变量。

clients是智商。IQueryable 在请求第一次迭代之前不会枚举其值。到那时,您的 DbContext 已被释放,因此枚举会引发异常。

要解决此问题,请使用类似

using (DBModels db = new DBModels())
{
var clients = Enumerable.Empty<Client>();
if (!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);
}
return View(clients.ToList());
}

从理论上讲,在调用 ToList(( 之前,您应该避免数据库调用,但是自从我走这条路以来已经有一段时间了。相反,我建议使用 LinqKit 中的 PredicateBuilder 来构建一个将完全针对数据库运行的查询,如下所示:

using (DBModels db = new DBModels())
{
var predicate = PredicateBuilder.New<Client>(true);
if (!String.IsNullOrEmpty(form.SearchString))
{
predicate.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)
{
predicate.And(t => t.Paid == form.IsChecked);
}
return View(db.Clients.Where(predicate).ToList());
}

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

相关内容

最新更新