Библиотека динамических запросов LINQ - PullRequest
7 голосов
/ 28 февраля 2011

Я создаю приложение ASP.Net MVC 3 с Entity Framework 4. Когда выполняются два фрагмента кода ниже, обе переменные (query1 и query2) имеют тип возврата

System.Data.Objects.ObjectQuery<Asset.Model.Equipment>

Query1 использует прямой экземпляр ObjectContext, однако Query2 использует шаблон репозитория, то есть он вызывает GetEquipment в EquipmentService, который, в свою очередь, вызывает метод с тем же именем в репозитории оборудования. Оба метода в Сервисе и Репозитории возвращают

IQueryable<Equipment>

Как, вот мой вопрос, почему запрос2 будет работать только тогда, когда я включу

using System.Linq.Dynamic;

Наверху моего контроллера

using (AssetEntities context = new AssetEntities())
        {
            var query1 = context.Equipments
            .OrderBy("it." + sidx + " " + sord)
            .Skip(pageIndex * pageSize)
            .Take(pageSize);
        }


        var query2 = equipService.GetEquipment()
            .OrderBy(sidx + " " + sord)
            .Skip(pageIndex * pageSize)
            .Take(pageSize);

Если я опускаю System.Linq.Dynamic из моего контроллера, я получаю ошибку в Query2 в

.OrderBy(sidx + " " + sord)

Какие состояния

The type arguments for method 'System.Linq.Queryable.OrderBy<TSource,TKey>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,TKey>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly

Кто-нибудь знает, почему query1 может работать без использования System.Linq.Dynamic, но этот запрос2 требует его выполнения?

Спасибо всем.

Ответы [ 2 ]

6 голосов
/ 01 марта 2011

В первом запросе context.Equipments имеет тип ObjectQuery<Equipment>. ObjectQuery<T> имеет метод OrderBy (строка) , который необходим для .OrderBy("it." + sidx + " " + sord). Итак, первый запрос работает.

Во втором запросе вы используете equipService.GetEquipment() типа IQueryable<Equipment>. IQueryable<T> имеет только метод расширения OrderBy с параметром Expression<Func<T, TKey>> вместо string. Таким образом, чтобы использовать OrderBy с IQueryable<Equipment>, вы должны написать что-то вроде

equipService.GetEquipment().OrderBy(e => e.equipmentID)

но это не то, что вы можете использовать. Вам нужен другой метод расширения, который может предоставить вам динамическую библиотеку запросов LINQ в форме System.Linq.Dynamic.

Во многих случаях LINQ to Entities имеет много ограничений , но в вашем случае он имеет больше преимуществ, чем LINQ to SQL. Поэтому я рекомендую вам придерживаться LINQ to Entities в вашем случае. Я уверен, что таким образом вы получите лучшую производительность благодаря встроенной поддержке всех функций непосредственно в Entity Framework, который вы используете.

Поскольку LINQ to Entities или ObjectQuery<Equipment> поддерживает метод Where(string) (точнее, ObjectQuery.Where (строковый предикат, params ObjectParameter [] параметры) метод), вы можете относительно легко реализовать фильтрацию / поиск в jqGrid. Использование .Where может быть

.Where("it.equipmentID < 100")

или

.Where("it.equipmentID < @maxId", new ObjectParameter ("maxId", 100))
Например,

(использование "maxId" вместо "@maxId" в ObjectParameter не является ошибкой ввода).

ОБНОВЛЕНО : В "ОБНОВЛЕННОЙ" части ответа вы можете найти пример , который показывает, как реализовать фильтрацию / поиск в jqGrid на основе идеи который я описал выше.

4 голосов
/ 28 февраля 2011

"it" - это значение по умолчанию ObjectQuery.Name значение свойства. Фактически, когда вы используете первый запрос, вы выполняете неявное предложение Entity SQL Order By, а во втором вы используете LINQ to Entities, и для правильной работы ему требуется пространство имен System.Linq.Dynamic.

...