Выражение Linq для разбиения на страницы / разбиения на страницы с динамическим OrderBy - PullRequest
3 голосов
/ 13 апреля 2011

All

Я пытаюсь заставить пейджинг работать с сеткой. Для этого мне нужно указать, по какому полю сортировать. Я не могу понять, как это сделать с помощью запроса Linq. Я использую .NET 4 / EF 4.1. В двух примерах ниже # 1 работает просто отлично. Проблема в том, что я передаю поле для сортировки, и поэтому мне нужно иметь возможность динамически изменять то, что мы сортируем. Когда я пытаюсь использовать строку, как в примере 2, она не сортируется по моему выражению. Есть ли способ сделать это? Кажется, многим людям нужна эта функциональность.

    [Example 1]
(from e in _context.MyEntity
 where (MyWhereClause)
 orderby e.SomeProperty Ascending
 select e).Skip(Offset).Take(MyCountPerPage);

    [Example 2]
(from e in _context.MyEntity
 where (MyWhereClause)
 orderby "SomeField, ASC"
 select e).Skip(Offset).Take(MyCountPerPage);

-Thanks-

Ответы [ 4 ]

4 голосов
/ 13 апреля 2011

Использование Динамический LINQ

1 голос
/ 13 апреля 2011

Во-первых, вы захотите извлечь свой заказ из запроса и использовать версию метода расширения,

var query = from e in _context.MyEntity
            where (MyWhereClause)
            select e;

query = query.DynamicOrderBy("property");

query = query.Skip(Offset).Take(MyCountPerPage);

Далее мы должны построить DynamicOrderBy, я предполагаю, что запроспротив какой-то IQueryable<T>.

//Need this to construct the query correctly
static MethodInfo s_orderBy = typeof(Queryable).GetMethods().First(m => m.Name == "OrderBy");

static IOrderedQueryable<T> DynamicOrderBy<T>(this IQueryable<T> source, string property)
{
    var expr = source.Expression;
    var p = Expression.Parameter(typeof(T), "x");
    var propInfo = typeof(T).GetProperty(property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
    var sortExpr = Expression.Lambda(Expression.Property(p, propInfo), p)
    var method = s_orderBy.MakeGenericMethod(typeof(T), propInfo.PropertyType);
    var call = Expression.Call(method, expr, sortExpr);
    var newQuery = source.Provider.CreateQuery<T>(call);
    return newQuery as IOrderedQueryable<T>;
}
0 голосов
/ 13 апреля 2011

Полагаю, вам это нужно для jqGrid.Ранее я писал ответ с полным проектом VS2008 , который вы можете использовать в качестве примера.

Основная идея заключается в том, что Entity Framwork можно использовать с ObjectQuery<T>которая поддерживает сортировку типа «SomeField, ASC», которая вам нужна.Таким образом, вы можете реализовать все, что вам нужно без Динамического расширения LINQ.Еще больше (см. здесь ) вы можете использовать конструкцию, подобную

.Where("it.equipmentID < @maxId", new ObjectParameter ("maxId", 100))

, где WHERE имеет строковые аргументы ("it.equipmentID <@maxId").Таким образом, вы можете реализовать все разбиение на страницы, сортировку и фильтрацию, используя строковые аргументы, которые вам нужны для jqGrid.Пример, с которого я начал свой ответ, демонстрирует, как вы можете это сделать. </p>

0 голосов
/ 13 апреля 2011
   var query = (from e in _context.MyEntity
     where (MyWhereClause)
     orderby e.SomeProperty Ascending
     select e).Skip(Offset).Take(MyCountPerPage);

    if(Ascendingflag)
       query = query.OrderBy(a = > SortExpression);
    else
       query = query.OrderByDescending(a = > SortExpression);
...