Описание проекта
Построитель 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));
}