Reexecuting IQueryable on different DbContext instance?

♀尐吖头ヾ 提交于 2019-12-12 18:50:41

问题


I'm creating a repository layer to encapsulate DbContext. I would like to expose a fluent interface for building query, and dispose and create a new DbContext every time after a query request is sent:

var repo = new EntityRepository();

repo = EntityRepository.FilterByAge(30).FilterByGender("Male");
var people = repo.GetPeople();
  // GetPeople() should send the request, get the result, then dispose
  // the old DbContext and create a new one

repo = repo.FilterByOccupation("Programmer");
var programmers = repo.GetPeople();
  // the age and gender filters should still apply here

Currently in my EntityRepository, I have a private DbContext and a IQueryable. In the Filter methods, I append the Linq methods onto the IQueryable. Then after finishing a request, I do:

db.Dispose();
db = new EntityContext();

But this does not work when I try to do another request. It says the DbContext has been disposed.

How do I keep the same query for a new DbContext?


回答1:


I ended up keeping a list of "filters", which are anonymous functions that takes in IQueryable and return IQueryable. Then I apply them on a short-live DbContext :

Repository:

private IList<Func<IQueryable<Person>, IQueryable<Person>>> filters;

public Repository FilterByAge(int age)
{
    var _filters = new List<Func<IQueryable<Person>, IQueryable<Person>>>(filters);
    _filters.Add(q => q.Where(e => e.Age == age));
    return new Repository(_filters);
}

public Repository OrderByName()
{
    var _filters = new List<Func<IQueryable<Entity>, IQueryable<Entity>>>(filters);
    _filters.Add(q => q.OrderBy(e => e.Name));
    return new Repository(_filters);
}

private IQueryable<Person> ApplyFilters(AppContext db)
{
    var result = db.People;
    foreach (var filter in filters)
    {
        result = filter(result);
    }
    return result;
}

public IEnumerable<Person> GetPeople()
{
    IEnumerable<Person> people;
    using (var db = new AppContext())
    {
        people = ApplyFilters(db).ToList();
    }
    return people;
}

Usage

private Repository repo = new Repository();

var peopleOfThirty = repo.FilterByAge(30);
var orderedByName = peopleOfThirty.OrderByName();

if (wantOrder)
{
    return peopleOfThirty.GetPeople();
}
else
{
    return orderedByName.GetPeople();
}

It works for my purposes. However, please let me know if there is any problem doing it this way. Thanks!



来源:https://stackoverflow.com/questions/20023187/reexecuting-iqueryable-on-different-dbcontext-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!