2017-01-04 20 views
-1

я читал о хранилище шаблона последние несколько дней, и все говорят об этом не разоблачить IQueryable из репозитория, как этот (как here и here):Не подвергая IQueryable и не нарушая принцип OC

public interface ICustomersRepository 
{ 
    IQueryable<Customer> Customers{ get; } 
} 

И для этого требуется большое количество разработчиков.

Но когда речь идет о фильтрации большого количества данных и пользовательских фильтров из пользовательского интерфейса (например, отчета с более чем 10 параметрами фильтра для поиска в данных более 1 миллиона записей), IQueryable?

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

Как упоминалось в других тонах, таких как this или this, у меня должны быть методы для каждого из отчетов, которые у меня есть в моих репозиториях, и они должны возвращать IEnumerable. Вот что мне непонятно:

Если у меня есть новый отчет, я должен изменить свой репозиторий для этого и добавить новый метод. И если я изменю свой репозиторий, я нарушил Open/Close principle.

Вот моя проблема: я не хочу раскрывать Iqueryable, а с другой стороны, я не хочу менять свой репозиторий для каждого отчета.

+0

Не возвращают IQueryable, но * принять один *, который можно использовать в качестве фильтра. Например, 'public SomeType [] Get (IQueryable filter)', который прост в использовании. Var result = someTypeRepo.Get (x => x.Id> 0) '. – Will

+0

Благодарю вас, что на самом деле может легко работать –

+0

Вы также можете взять IQueryables, которые отображают свойства навигации, которые вы хотите включить в результат. – Will

ответ

0

Репозиторий - это абстракция на вашем уровне доступа к данным (DAL). В Java они также известны как DAO (объекты доступа к данным). Таким образом, выставляя IQueryable<T> в репозитории, это плохая практика, поэтому вы связываете запросы LINQ с кодом клиента.

Чтобы исправить это, вы должны создать объект, который будет следовать шаблону команды со всеми параметрами фильтрации, которые вы поддерживаете. Затем верните List<T> или любую сортированную коллекцию, которую вы хотите использовать (возможно, IList<T> более подходит).

Пример

class BookFilter 
{ 
    public string NameStartsWith { get; set; } 
    public string ISBN { get; set; } 
    public DateTime PublishedAfter { get; set; } 
    // .... 
} 

public interface IBookRepository 
{ 
    IList<Book> Filter(BookFilter filter); 
} 
+0

спасибо за ваш ответ, так как вы говорите, что для каждого отчета я должен изменить свой репозиторий? потому что клиент всегда запрашивает новый отчет, и я должен изменить свой репозиторий, и я думаю, что это насилие. Open close main –

+0

Это может быть не удобный вариант, если то, что вы делаете, сообщает. Я отвечал на то, что вы спросили. Несмотря на то, что вы показываете сценарий, когда требования меняются, так будет и BookFilter и поддерживать новые фильтры, которые вы ранее не поддерживали. Принимая дистанцию ​​с шаблоном репозитория, если то, что вы делаете, сообщает, возможно, вы можете отказаться от использования непосредственно 'IQueryable', больше, если отчеты могут измениться или расти. – jorgonor

+0

спасибо, что я был смущен примерно –