Описание проекта

Построитель CAML-запросов представляет собой набор инструментов для быстрого и удобного создания текстов CAML-запросов через лямбда-выражения.

Преимущества

  • создание CAML-запроса без необходимости знать все тонкости его синтаксиса
  • простой в использовании инструмент на основе лямбда-выражений
  • можно использовать как в решениях уровня фермы (.NET 3.5), так и на уровне SandBox-решений, напр. Silverlight
  • можно использовать как напрямую (для поля указывается его название и тип), так и с использованием классов описаний полей из Вашей инфраструктуры; для этого добавлены компоненты:
    • перечисление типов полей для Sharepoint
    • базовый класс описания поля списка Sharepoint

Использование CamlQueryCreator

Предположим, нужно создать такой CAML-запрос:

<OrderBy>
   <FieldRef Name='TextField1'/>
   <FieldRef Name='IntegerField'/>
</OrderBy>
<Where>
   <And>
      <And>
         <Eq>
            <FieldRef Name='UserField'/>
            <Value Type='Integer'><UserID Type='Integer'/></Value>
         </Eq>
         <Eq>
            <FieldRef Name='TextField1'/>
            <Value Type='Text'>TextValue1</Value>
         </Eq>
      </And>
      <Or>
         <Eq>
            <FieldRef Name='IntegerField'/>
            <Value Type='Integer'>100</Value>
         </Eq>
         <Eq>
            <FieldRef Name='TextField2'/>
            <Value Type='Text'>TextValue2</Value>
         </Eq>
      </Or>
   </And>
</Where>


т.е., зная названия полей,
    const string userFieldName = "UserField";
    const string textFieldName1 = "TextField1";
    const string textFieldName2 = "TextField2";
    const string integerFieldName = "IntegerField";
а так же их типы, мы хотим получить вот такую строку:
<OrderBy><FieldRef Name='TextField1'/><FieldRef Name='IntegerField'/></OrderBy><Where><And><And><Eq><FieldRef Name='UserField'/><Value Type='Integer'><UserID Type='Integer'/></Value></Eq><Eq><FieldRef Name='TextField1'/><Value Type='Text'>TextValue1</Value></Eq></And><Or><Eq><FieldRef Name='IntegerField'/><Value Type='Integer'>100</Value></Eq><Eq><FieldRef Name='TextField2'/><Value Type='Text'>TextValue2</Value></Eq></Or></And></Where>


Подключаем к нашему проекту соответствующую сборку:
  • если это решение уровня фермы, подключаем CamlQueryCreator.Net35
  • если это SandBox-решение, подключаем CamlQueryCreator.Portable

Получаем результат:
return Caml.GetQuery(
    b => b.Where()
          .And(i => i.And(j => j.CurrentUserEq(userFieldName),
                          j => j.Eq(textFieldName1, FieldTypeKind.Text, textValue1)),
               i => i.Or(j => j.Eq(integerFieldName, FieldTypeKind.Integer, integerValue),
                         j => j.Eq(textFieldName2, FieldTypeKind.Text, textValue2))),
    b => b.OrderBy(textFieldName1)
          .AndOrderBy(integerFieldName));

Все вместе будет выглядеть вот так:
public static string GetQuery()
{
    const string userFieldName = "UserField";
    const string textFieldName1 = "TextField1";
    const string textFieldName2 = "TextField2";
    const string integerFieldName = "IntegerField";

    const string textValue1 = "TextValue1";
    const string textValue2 = "TextValue2";
    const int integerValue = 100;

    return Caml.GetQuery(
        b => b.Where()
              .And(i => i.And(j => j.CurrentUserEq(userFieldName),
                              j => j.Eq(textFieldName1, FieldTypeKind.Text, textValue1)),
                   i => i.Or(j => j.Eq(integerFieldName, FieldTypeKind.Integer, integerValue),
                             j => j.Eq(textFieldName2, FieldTypeKind.Text, textValue2))),
        b => b.OrderBy(textFieldName1)
              .AndOrderBy(integerFieldName));
}

Теперь рассмотрим случай, когда в проекте уже существуют классы, описывающие поля списков Sharepoint. Для того, чтобы построитель запросов мог их использовать, эти классы должны быть унаследованы от ListFieldInfoBase, который содержит внутреннее название поля и его тип. В нашем примере такой класс будет всего один:
public class ListFieldInfo : ListFieldInfoBase
{
    public ListFieldInfo(string name, FieldTypeKind fieldType): base(name, fieldType)
    {
    }
}

Описания полей в нашем примере будут вот такие:
var userFieldInfo = new ListFieldInfo(userFieldName, FieldTypeKind.User);
var textFieldInfo1 = new ListFieldInfo(textFieldName1, FieldTypeKind.Text);
var textFieldInfo2 = new ListFieldInfo(textFieldName2, FieldTypeKind.Text);
var integerFieldInfo = new ListFieldInfo(integerFieldName, FieldTypeKind.Integer);

И тогда наш запрос строится еще проще:
return Caml.GetQuery(
    b => b.Where()
          .And(i => i.And(j => j.CurrentUserEq(userFieldInfo),
                          j => j.Eq(textFieldInfo1, textValue1)),
               i => i.Or(j => j.Eq(integerFieldInfo, integerValue),
                         j => j.Eq(textFieldInfo2, textValue2))),
    b => b.OrderBy(textFieldInfo1)
          .AndOrderBy(integerFieldInfo));

Все вместе будет выглядеть вот так:
public static string GetQuery()
{
    const string userFieldName = "UserField";
    const string textFieldName1 = "TextField1";
    const string textFieldName2 = "TextField2";
    const string integerFieldName = "IntegerField";

    const string textValue1 = "TextValue1";
    const string textValue2 = "TextValue2";
    const int integerValue = 100;

    var userFieldInfo = new ListFieldInfo(userFieldName, FieldTypeKind.User);
    var textFieldInfo1 = new ListFieldInfo(textFieldName1, FieldTypeKind.Text);
    var textFieldInfo2 = new ListFieldInfo(textFieldName2, FieldTypeKind.Text);
    var integerFieldInfo = new ListFieldInfo(integerFieldName, FieldTypeKind.Integer);

    return Caml.GetQuery(
        b => b.Where()
              .And(i => i.And(j => j.CurrentUserEq(userFieldInfo),
                              j => j.Eq(textFieldInfo1, textValue1)),
                   i => i.Or(j => j.Eq(integerFieldInfo, integerValue),
                             j => j.Eq(textFieldInfo2, textValue2))),
        b => b.OrderBy(textFieldInfo1)
              .AndOrderBy(integerFieldInfo));
}

Last edited Jan 5, 2014 at 7:57 AM by AVBaklan, version 9