2015-11-17 2 views
4

Существует несколько хороших блогов о том, как реализовать шаблон хранилища вместе с шаблоном единицы работы с использованием общих классов.Шаблон репозитория Framework Entity Framework почему бы не вернуть Iqueryable?

Implementing a Data Access Layer with Entity Framework 6.1

Implementing the Repository and Unit of Work Patterns

Идея заключается в том, чтобы определить общий интерфейс IRepository и класс Repository, который скрывает, как данные фактически обращались. Доступ к нему можно получить с помощью Entity Framework DbContext, или, может быть, репозиторий является сборкой памяти для модульного тестирования.

public interface public interface IRepository<T> where T : class 
{ 
    T GetById(int Id); 
    void DeleteById(int Id); 

    void Add(T entity); 
    void Update(T entity); 

    etc. 
} 

Довольно часто я вижу, что некоторые функции запроса добавляются, которые похожи на запрашиваемые и/или Перечислимые функции.

Например, в Implementing a data access layer я вижу:

/// Returns an IEnumerable based on the query, order clause and the properties included 
/// <param name="query">Link query for filtering.</param> 
/// <param name="orderBy">Link query for sorting.</param> 
/// <param name="includeProperties">Navigation properties seperated by comma for eager loading.</param> 
/// <returns>IEnumerable containing the resulting entity set.</returns> 
IEnumerable<T> GetByQuery(Expression<Func<T, bool>> query = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = ""); 

/// <summary> 
/// Returns the first matching entity based on the query. 
/// </summary> 
/// <param name="predicate"></param> 
/// <returns></returns> 
T GetFirst(Expression<Func<T, bool>> predicate); 

Если интерфейс имел функцию IQueryable GetQuery(), то я бы не сделать такие функции, как GetFirst() и GetByQuery().

Вопрос: Почему это не рекомендуется? Могут ли люди изменить данные нежелательным образом?

ответ

4

Одна из причин, почему мы используем шаблон хранилище для инкапсулирования жира запросов. Эти запросы затрудняют чтение, понимание и проверку действий в ASP.NET MVC-контроллерах. Кроме того, по мере роста вашего приложения шансы на повторение жирного запроса в разных местах возрастают. С шаблоном репозитория мы инкапсулируем эти запросы в классы репозитория. Результат - более тонкие, более чистые, более удобные и простые в проверке действия. Рассмотрим следующий пример:

var orders = context.Orders 
    .Include(o => o.Details) 
     .ThenInclude(d => d.Product) 
    .Where(o => o.CustomerId == 1234); 

Здесь мы непосредственно используем DbContext без шаблона репозитория. Когда ваши методы репозитория возвращают IQueryable, кто-то собирается получить этот IQueryable и составить запрос поверх него. Вот результат:

var orders = repository.GetOrders() 
    .Include(o => o.Details) 
     .ThenInclude(d => d.Product) 
    .Where(o => o.CustomerId == 1234); 

Вы видите разницу между этими двумя фрагментами кода? Единственная разница в первой строке. В первом примере мы используем context.Orders, во втором мы используем repository.GetOrders(). Итак, какова проблема в решении этого репозитория? Ничего!

Ваши репозитории должны возвращать объекты домена. Таким образом, метод GetOrders() должен возвращать IEnumerable.При этом второй пример может быть переписан как:

var orders = repository.GetOrders(1234); 

См. Разницу? Источник: г-н Хамедани blog

+2

Эй, это скопируйте текст из этого блога: https://programmingwithmosh.com/entity-framework/common-mistakes-with-the-repository-pattern/. Вы должны были упомянуть, что информация «заимствована» -))) –

4

Это не рекомендуется, поскольку это приведет к аннулированию шаблона репозитория. Цель этого шаблона - сохранить вашу реализацию DAL отдельно от других ваших проектов с помощью абстракции.

По существу возвращение IQueryable вернет инструкцию TSQL и НЕ означает, что любые проекты, ссылающиеся на ваш DAL, потребуют дополнительных ссылок на EF для выполнения выполнения запроса. Эта «утечка данных» сделает ваши проекты более плотными и, следовательно, противоречит принципу разделения внимания.

Вы можете прочитать больше о хранилище шаблона и его преимущества здесь: http://www.codeproject.com/Articles/526874/Repositorypluspattern-cplusdoneplusright

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