Подтвердить что ты не робот

Linq-to-Entities Динамическая сортировка

Это мой запрос, как я могу использовать строку в качестве параметра orderby?

string sortColumn="Title";

var  items = (from ltem in ctxModel.Items
              where ltem.ItemID == vId
              orderby //something here
              select ltem).Skip(PageSize * PageIndex).Take(PageSize);

UPDATE:
Я не могу просто OrderBy набор результатов, потому что мне нужно сначала сортировать, а только THEN на страницу.

4b9b3361

Ответ 1

Другие предложили использовать динамическую ссылку или другие библиотеки. Лично, я бы не вносил библиотечную зависимость для такой небольшой задачи. Но два других пути, которые вы можете предпринять, - это...

  • Использовать синтаксис вызова объекта и динамически строить дерево выражений запроса. Например...

См. http://blog.cincura.net/229310-sorting-in-iqueryable-using-string-as-column-name/

В этом сценарии важно рассмотреть Отложенное выполнение. Вы можете безопасно построить свой запрос, который возвращает объект IQueryable, а затем запустить сортировку запроса объекта на этом объекте. Ваш запрос будет запускаться только один раз, когда данные будут фактически доступны.

Вышеупомянутое сообщение в блоге - это пример того, как вы можете использовать API выражения для построения дерева выражений, который вы можете использовать для своего OrderBy. Это просто звучит сложно. Статья MSDN может быть лучшей ссылкой. См. Как использовать деревья выражений для создания динамических запросов в MSDN.

Или

  • Используйте простой маршрут и просто используйте переключатель для заголовка для всего запроса.

Eg.

ItemType items = default(ItemType);
switch(sortColumn)
{
     case "Title":
     {
           items = ctxModel.Items
                    .Where(i => i.ItemID == vId)
                    .OrderBy( i => i.Title);
     }
     break;
 }

Ответ 2

Я использую этот помощник:

public static class OrderExt
{
    private static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName, SortDirection descending, bool anotherLevel = false)
    {
        var param = Expression.Parameter(typeof(T), string.Empty);
        var property = Expression.PropertyOrField(param, propertyName);
        var sort = Expression.Lambda(property, param);

        var call = Expression.Call(
            typeof (Queryable),
            (!anotherLevel ? "OrderBy" : "ThenBy") +
            (descending == SortDirection.Descending ? "Descending" : string.Empty),
            new[] {typeof (T), property.Type},
            source.Expression,
            Expression.Quote(sort));

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
    }
}

чтобы вызвать помощника, например:

string sort = HttpContext.Current.Request.QueryString["sort"];
var products = _productRepository.OrderBy(sort, SortDirection.Ascending);

Ответ 3

Здесь другая альтернатива, EntitySorter. Позволяет немного динамического LINQ со строками, но обертывает операцию в объекте, как с шаблон объекта запроса. Он позволяет сортировать по строкам и по типу безопасных конструкций. Вот несколько примеров:

// Ways of defining an entity sorter
// 1. Using strings:
IEntitySorter<Person> sorter = EntitySorter<Person>
    .OrderBy("Address.City")
    .ThenByDescending("Id");

// 2. Defining a sorter with lambda's
IEntitySorter<Person> sorter = EntitySorter<Person>
    .OrderByDescending(p => p.Name)
    .ThenBy(p => p.Id)
    .ThenByDescending(p => p.Address.City);

// 3. Using a LINQ query
IEntitySorter<Person> sorter =
    from person in EntitySorter<Person>.AsQueryable()
    orderby person.Name descending, person.Address.City
    select person;

// And you can pass a sorter from your presentation layer
// to your business layer, and you business layer may look
// like this:
static Person[] GetAllPersons(IEntitySorter<Person> sorter)
{
    using (var db = ContextFactory.CreateContext())
    {
        IOrderedQueryable<Person> sortedList =
            sorter.Sort(db.Persons);

        return sortedList.ToArray();
    }
}

Здесь вы можете найти код .

Ответ 4

По-видимому, другие намеки на Dynamic Linq недостаточно ясны. Позвольте мне пролить свет.

Использование Dynamic Linq не обязательно указывает на необходимость зависимости от сборки.

Динамический Linq содержится в одном исходном файле, если я не ошибаюсь, который включен в образцы С#, которые каждый должен был по крайней мере просматривать в течение последних 3 лет, и их можно легко отбросить в проект, а namespaced to предотвращать столкновения, тем самым предоставляя услуги построения выражений, которые могут быть использованы везде, где это необходимо.

Я рассматриваю возможность безопасного построения выражения из произвольно произвольного string, который может быть легко построен на лету, чтобы быть лучшим примером "динамического".

Рассмотрим:

    var query = northwind.Products
                         .Where("CategoryID = 3 AND UnitPrice > 3")
                         .OrderBy("SupplierID");

Ответ 5

Этот запрос выглядит так: вы используете пользовательскую привязку данных и/или объект ObjectDataSource, независимо от того, существует ли способ сделать это с помощью метода расширения, который принимает выражение сортировки и динамически добавляет вызов (выражение) OrderBy() в linq запрос. Я зарегистрировал, как в сообщение в блоге некоторое время назад, которое по совпадению было частью этого SO-вопроса. Если вам нужно больше, вы можете использовать динамический linq, который довольно хорошо документирован от scottgu.

EDIT: использование метода расширения сделает его похожим на

string sortColumn="Title";

    var  items = (from ltem in ctxModel.Items
                  where ltem.ItemID == vId
                  select ltem).Skip(PageSize * PageIndex).Take(PageSize).OrderBy(sortColumn);