在不同的DbContext实例上重新执行IQueryable?

时间:2013-11-16 20:05:57

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

我正在创建一个存储库层来封装DbContext。 我想公开一个流畅的界面来构建查询,并在每次发送查询请求后处理并创建一个新的DbContext

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

目前在我的EntityRepository中,我有一个私人DbContext和一个IQueryable。在Filter方法中,我将Linq方法附加到IQueryable上。然后在完成请求后,我这样做:

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

但是当我尝试做另一个请求时,这不起作用。它说DbContext已被处置。

如何为新DbContext保留相同的查询?

1 个答案:

答案 0 :(得分:1)

我最后保留了一个“过滤器”列表,这些过滤器是一个匿名函数,它接收IQueryable并返回IQueryable。然后我将它们应用于短期DbContext

<强>存储库:

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

<强>用法

private Repository repo = new Repository();

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

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

它适用于我的目的。但是,如果这样做有任何问题,请告诉我。谢谢!