Динамическое создание OrderBy выражений с помощью Camlex.NET

На этой неделе состоялся очередной релиз нашего проекта Camlex.NET, в который была добавлена новая функциональность – динамические OrderBy выражения. Camlex.NET был выпущен для Sharepoint разработчиков для упрощения создания CAML запросов. Как и много других фич, динамические OrderBy выражения были инициированы дискуссией на сайте проекта на Codeplex, т.е. является результатом обратной связи с разработчиками, использующими Camlex (спасибо пользователю с ником umike за его вопрос). Так что если вы думаете, что какая-либо функциональность будет полезной для Camlex-а, не стесняйтесь сообщать нам об этом через раздел дискуссий. На этом мое небольшое вступление заканчивается и я перехожу непосредственно к описанию новой функциональности в Camlex.NET.

Во многих сценариях, когда нам нужно создать CAML запрос программно на основе каких-либо параметров, на этапе компиляции мы не знаем, какие именно поля будут использоваться для сортировки. Например, предположим, что у нас есть grid view контрол, который отображает коллекцию item-ов, которая в свою очередь получена из списка Sharepoint с использованием CAML. Пользователи могут сортировать записи по нескольким полям по возрастанию и убыванию. Мы не знаем, какой CAML запрос будет использован в каждом случае. Для таких сценариев динамические OrderBy выражения были добавлены в Camlex. Теперь разработчики могут создавать OrderBy выражения в CAML запросах, используя параметры, полученные, к примеру, из UI или пользовательского ввода. Новый метод был добавлен в интерфейс IQuery, который является базовым интерфейсом Camlex-а. Этот метод принимает на вход список C# выражений для построения OrderBy части CAML запроса (каждое такое выражение имеет вид x => x[“Title”] или x => x[“Title”] as Camlex.Asc – см. http://camlex.codeplex.com – Scenario 6. Query with sorting (OrderBy)):

public interface IQuery
{
...
IQuery OrderBy(IEnumerable<Expression<Func<SPListItem, object>>> expressions);
}

Таким образом, теперь вы можете динамически создавать список выражений для OrderBy в runtime и передавать его непосредственно в Camlex, как показано в следующем примере:

var orderByList = new List<Expression<Func<SPListItem, object>>>();
orderByList.Add(x => x["Title"] as Camlex.Asc);
orderByList.Add(y => y["Date"] as Camlex.Desc);

var caml = Camlex.Query().OrderBy(orderByList).ToString();

В итоге мы получим следующий CAML запрос:

<OrderBy>
<FieldRef Name="Title" Ascending="True" />
<FieldRef Name="Date" Ascending="False" />
</OrderBy>

Также вы можете выполнять сортировку по одному полю путем добавления единственного элемента в список выражений.

Пример выше целиком взят из юнит тестов (которыми полностью покрыт Camlex. Если вам интересно посмотреть, как это сделано, можете скачать исходники здесь). Давайте рассмотрим более приближенный к реальности пример: в общем случае у нас есть некий список пар (имя поля, направление сортировки), и нам нужно преобразовать его к типу, который ожидает Camlex (IEnumerable<Expression<Func<SPListItem, object>>>). Задача решается одной строчкой кода:

var sortParams = new[]
                     {
                         new { Title = "Title", Direction = "Asc" },
                         new { Title = "Date", Direction = "Desc" },
                     };
var list =
    sortParams.Select(
        t => t.Direction == "Asc" ? (Expression<Func<SPListItem, object>>)(x => x[t.Title] as Camlex.Asc) : x => x[t.Title] as Camlex.Desc);

var query = Camlex.Query().OrderBy(list).ToString();
Console.WriteLine(query);

Для удобочитаемости я разбил преобразование на несколько строк, так что формально строчка не одна, тем не менее оно выполнено одним выражением :). Кроме этого я добавил приведение типов к первому выражению тринарного оператора (см. (Expression<Func<SPListItem, object>>)), т.к. без него компилятор выдает ошибку:

Type of conditional expression cannot be determined because there is no implicit conversion between ‘lambda expression’ and ‘lambda expression’

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

Как видите, если не считать досадной мелочи с приведением типов, преобразование делается достаточно просто. Надеюсь, что новая функциональность будет полезной в вашей повседневной работе.

Advertisements

Об авторе sadomovalex

Старший инженер, team lead, консультант. Работаю в стеке .Net. Последние несколько лет занимаюсь разработкой enterprise приложений под Sharepoint, чему и будет в основном посвящена тематика этого блога. Также активно использую и интересуюсь ASP.Net MVC, DDD, TDD, Agile. Активно участвую в жизни многих профессиональных сообществ, SPb .Net UG, SPb ALT.Net, rsdn, Finland SP UG и др.
Запись опубликована в рубрике CAML, Camlex.NET, Sharepoint. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s