2015-06-14 2 views
5

Я читаю на общих хранилищах. Я продолжаю спотыкаться на части кода, которые я не понимаю. Я не знаю, есть ли у них определенное имя или нет.Что это называется и что он делает? (Часть общего репозитория)

Это самый сложный пример, который я видел:

IEnumerable<T> GetByQuery(
    Expression<Func<T, bool>> query = null, 
    Func<IQueryable<T>, IOrderedQueryable<T>> orderby = null, 
    string includeProperties = ""); 

Я знаю, что это (независимо от того, что это), очевидно, возвращает IEnumerable, но я понятия не имею, как читать этот беспорядок абракадаброй не говоря уже о том, как чтобы использовать его.

Редактировать: Мне больше интересно узнать, что это пример из, чем разбивка этого конкретного примера. Мне нужно знать, что они вызывают, прежде чем я смогу найти что-то, что объясняет синтаксис. LINQ ??

Редакция 2: Я задаю гораздо более простой вопрос, чем тот, на который вы ответите. Все, что я хочу знать, это «какие-то условия поиска Я могу использовать для изучения вышеуказанного кода?»

+0

Мне нравится, что вы использовали «gobbledygook». Выражения могут выглядеть беспорядочно. –

+0

Вам нужно быть более конкретным, о том, какие части gook являются gobbledy. Вы знаете, что такое дженерики? Вы знаете, что такое делегат? Вы смущены тем, как работает 'IQueryable ''? Вы не понимаете бит 'Expression <>'? Есть отличный ответ, который уже разрушает этот конкретный метод, но, возможно, эти термины помогут вам провести основные исследования. –

+0

Я слышал о дженериках и делегатах. Я никогда не видел ничего с условиями IQueryable, Func или Expression <> раньше. Единственное «выражение», которое я когда-либо слышал, касалось математики (как в 2 + 2). Я предполагаю, что есть определенный контекст, в котором эти вещи происходят вместе. Это то, что я пытаюсь понять. – rayden54

ответ

9

Обратите внимание, что все это чрезвычайно образованное предположение, основанное на том, как работает IQueryable<T>.

разбить его на три части:

Expression<Func<T, bool>> query = null 

Это где положение, это та же подпись, которая передается методу Where расширения на IQueryable<T>.

Вы должны передать выражение, которое представлено в коде так же, как и лямбда; компилятор C# знает, что параметр ищет Expression и скомпилирует его в дереве выражений, а не в делегате.

Например, если предположить T является Person класс с int свойством Age, вы можете отфильтровать Person возвращенное IQueryable<Person>, который 30 лет и старше со следующим:

p => p.Age > 30 

Func<IQueryable<T>, IOrderedQueryable<T>> orderBy 

Это просто делегат, который, если предоставлен, позволит вам установить заказ. Предполагая, что вы хотите Person экземпляров упорядоченных по возрасту, вы будете использовать:

q => q.OrderBy(p => p.Age) 

Это потому, что тип возвращаемого значение IOrderedQueryable<T>, которые, как методы расширения, такие как ThenBy и ThenByDescending всплывают только после того, как вы называете OrderBy и OrderByDescending; эти методы расширения определяются только на IOrderedQueryable<T> (это немного больше, чем интерфейс маркера).


includeProperties 

Это нарушает правила, что он с помощью Entity Framework под одеялом. Когда вы вызываете Include в Entity Framework, он позволяет вам получать связанные объекты (через внешний ключ) и загружать объекты, связанные с объектом, возвращаемым в запросе.

Скажем, класс Person имеет свойство Father типа Person. Если вы хотите запросить Person экземпляры и вернуть возвращаемое свойство Father, тогда вы должны позвонить Include("Father"), чтобы указать, что не только Entity Framework получит экземпляры Person, но также должно разрешить отношения Father.


IEnumerable<T> возвращаемый тип

Это возвращается, так что вы не имеете доступа к IQueryable<T> инстанции и сил вы материализовать набор результатов (как вы итерацию через него).

Реализация, которая делает это должно быть возвращая материализованный список (IReadOnlyCollection<T>), или что-то, что не только (предположительно) отливка IQueryable<T> к IEnumerable<T>.

Это также показатель доверия, которым обладает автор метода для клиентов; поскольку IQueryable<T> не возвращается, он указывает, что он не доверяет клиентам не делать неэффективные вызовы БД (что является актуальной проблемой).

+3

Я должен отметить, что мое мнение о том, что данный метод определенно является препятствием; это действительно делает использование Entity Framework намного сложнее. В идеале вы должны иметь доступ к «IQueryable » (с некоторой настройкой основных фильтров/заказов) и позволить вызывающему агенту самостоятельно реализовать список, опционально добавляя некоторые дополнительные логики/операции запроса перед этим. – casperOne

+0

Я тоже не знаю, что это, боюсь. – rayden54

+2

@ user2146821, если вы не понимаете этот ответ, который достаточно ясен и хороший сбой, у вас есть некоторые фундаментальные исследования. – usr

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