2013-02-14 2 views
0

У нас есть многоуровневое приложение, в котором все репозитории основаны на (родном) базовом классе GenericRepository (где T является объектом в модели), который предоставляет такие методы, как GetContext(), GetObjectSet() и скоро. Мы разрешаем хранилищам, которые наследуют это для доступа к контексту, поскольку они должны вызывать Include(), поскольку мы передаем данные через службу WCF, поэтому нужно загружать все связанные с ними объекты с нетерпением.Можно ли перехватить Entity Framework при загрузке данных из базы данных?

Все наши объекты реализуют интерфейс, обладающий активным свойством bool, и то, что мы хотим сделать, это перехват выполнения запроса и фильтрация по свойству Active, так что любой запрос возвращает только объекты, где это установлено к истине.

Можно ли это сделать? В Lightswitch, который построен на EF, есть событие, которое вы можете захватить, которое срабатывает прямо в глубинах выполнения запроса и позволяет вам выполнять такую ​​фильтрацию. Я не могу ничего найти в самом EF, который позволяет это.

У вас есть идеи? Спасибо

ответ

1

В EF 5 Include является метод расширения на IQueryable, так что вы можете сделать это:

var query = dbSet.Where(o => o.IsActive).Include(...) 

Это означает, что вам не придется возвращать DbSet<T> из вашего общего хранилища - это должно быть в порядке для возврата IQueryable<T>.

Если это отвечает вашим требованиям, вы можете добавить пункт Where к вашему универсального метода репозитория:

partial class GenericRepository<T> 
{ 
    public IQueryable<T> Query(bool includeInactive = false) 
    { 
    return ctx.Set<T>().Where(o => includeInactive || o.IsActive); 
    } 
} 
+0

Привет, Николас, спасибо за ответ. Я не знал об этом EF5. Я недостаточно глубоко вникнул в это, чтобы сказать наверняка, но похоже, что это может быть даже в некоторых версиях v4.x. Во всяком случае, кроме того, что некоторые проблемы вызывают самообучающиеся объекты, это похоже на ответ. Еще раз спасибо. –

+0

@AvrohomYisroel Glad Я мог бы помочь :) –

1

Лучший способ, которым я могу придумать это, - это использовать методы репозитория в выражении (т. Е. Expression<Func<T, bool>> predicate). Таким образом, вы можете выполнять все свои запросы в самом реальном репозитории (и, таким образом, не позволять клиентскому коду каким-либо образом обращаться к логике уровня данных), к которому вы можете добавить Where, прежде чем вернуться из метода репозитория, чтобы захватить эти которые являются активными.

Пример этого стиля, который я использовал следующий:

public IQueryable<T> Grab(Expression<Func<T, bool>> predicate) 
    { 
    return DbSet.Where(predicate); 
    } 

Где DbSet фактической таблицы, вы пытаетесь запросить. Таким образом, вы можете добавить .Where(x => x.Active) до конца, не выполнить ли он в отношении базы данных (спасибо, отложенное выполнение!) И все же получить точные записи, которые вы ищете.

+0

Спасибо за предложение. К сожалению, это очень зрелый проект, и рефакторинг кода репозитория просто не вариант, его большая часть. Вот почему мы надеялись сделать это в общем репозитории, так как мы можем изменить один файл, и все остальные увидели бы изменение. Если бы у нас была роскошь крупного переписывания, мы бы сделали многое по-другому! Спасибо, в любом случае. –

Смежные вопросы