Reputation: 215
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);
}
}
Don't understand why this error is happening. I added a search box to search through the database. I also added a tick box to show the unpaid clients. When I change
return View(clients);
back to
return View(db.Client.ToList());
it works but is what i am trying to avoid as it shows all the list not the "clients" variable which shows the ones from the SearchString.
Upvotes: 4
Views: 1058
Reputation: 1
IQueryable type of data structures are for iteration purpose mainly, these won't don't yield value until ToList is used. That's why your object is not evaluated after the dbcontext is disposed.
Upvotes: 0
Reputation: 21201
clients
is an IQueryable. IQueryable doesn't enumerate it's values until the first iteration is requested. By that time, your DbContext has already been disposed, so the enumeration throws an exception.
To fix that, use something like
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());
}
In theory, you should avoid the database call until the ToList() is called, but it's been awhile since I went that route. Instead, I'd recommend using PredicateBuilder, from LinqKit, to build a query that will be completely run against the database, like so:
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());
}
Upvotes: 2