Project Description
Camlex.NET simplifies creating of CAML queries for Windows SharePoint Services by using expression trees.

If you find Camlex.NET useful, you may support its development via Donate button on the online version http://camlex-online.org.

Client object model
Version for Client object model is also available. It can be downloaded from here: Camlex.Client.

Online version
You can convert your existing CAML queries to C# code for Camlex.NET using online service powered by Camlex: http://camlex-online.org.
powered by ndepend

Installation Instructions
In order to start working with Camlex.NET, please download and reference Camlex.NET.dll assembly in your project. After that you can create CAML queries using lambda expressions.
Starting from version 3.0 you can install NuGet package for Camlex from online packages gallery:
Install-Package Camlex.NET.dll

or Client version:
Install-Package Camlex.Client.dll


Quick Start
Camlex.NET is a new technique in Sharepoint development. It abstracts developers from syntax of CAML queries and helps them to concentrate on business tasks. With Camlex.NET developers could think about WHAT they need to do, instead of HOW to do it. It also brings the following advantages for Sharepoint developers:
  • Compile time checking of expressions
  • Natural and intuitive syntax using lambda expressions and fluent interfaces
  • Support for native .Net types (int, strings, bool, DateTime, Guid) and operations (==, !=, >, <, etc)
  • Support for Sharepoint-specific data types
  • Ability to specify non-constant expressions inside filtering conditions (variables, method calls, etc)
  • Fully customizable resulting query object
  • Ability to build dynamic filtering conditions and join them using And/Or logical joins
  • Search by lookup fields using LookupValue or LookupId

Now let's consider some basic scenarios:

Scenario 1. Simple query
Suppose that you need to select all items which have Status field set to Completed (following is the standard syntax of CAML):
<Where>
  <Eq>
    <FieldRef Name="Status" />
    <Value Type="Text">Completed</Value>
  </Eq>
</Where>
This query can be made with Camlex using the following syntax:
string caml =
    Camlex.Query()
        .Where(x => (string)x["Status"] == "Completed").ToString();
Notice, other comparison operations like “<”, “<=”, “>”, “>=” are supported as well.

Scenario 2. Query with “and”/”or” conditions
Suppose that you need to select items which have ProductID = 1000 and IsCompleted set to false or null. Syntax of appropriate standard CAML query follows:
<Where>
  <And>
    <Eq>
      <FieldRef Name="ProductID" />
      <Value Type="Integer">1000</Value>
    </Eq>
    <Or>
      <Eq>
        <FieldRef Name="IsCompleted" />
        <Value Type="Boolean">0</Value>
      </Eq>
      <IsNull>
        <FieldRef Name="IsCompleted" />
      </IsNull>
    </Or>
  </And>
</Where>
With help of Camlex it could be converted using following natural syntax:
var caml =
    Camlex.Query()
        .Where(x => (int)x["ProductID"] == 1000 && ((bool)x["IsCompleted"] == false || x["IsCompleted"] == null))
            .ToString();

Scenario 3. Query with DateTime
Lets suppose that you need to retrieve items which were modified on 01-Jan-2010:
<Where>
  <Eq>
    <FieldRef Name="Modified" />
    <Value Type="DateTime">2010-01-01T12:00:00Z</Value>
  </Eq>
</Where>
Using Camlex you can simply write:
var caml =
    Camlex.Query()
        .Where(x => (DateTime)x["Modified"] == new DateTime(2010, 01, 01)).ToString();

Scenario 4. Query with BeginsWith and Contains operations
Consider the query that should return items which Title field starts with “Task” and Project field contains “Camlex”:
<Where>
  <And>
    <BeginsWith>
      <FieldRef Name="Title" />
      <Value Type="Text">Task</Value>
    </BeginsWith>
    <Contains>
      <FieldRef Name="Project" />
      <Value Type="Text">Camlex</Value>
    </Contains>
  </And>
</Where>
You can achieve result using the following natural syntax:
var caml =
    Camlex.Query()
        .Where(x => ((string)x["Title"]).StartsWith("Task") && ((string)x["Project"]).Contains("Camlex"))
            .ToString();

Scenario 5. Query with none C# native data types
Suppose that you need to retrieve all items modified by Administrator:
<Where>
  <Eq>
    <FieldRef Name="Editor" />
    <Value Type="User">Administrator</Value>
  </Eq>
</Where>
Notice that value is of Sharepoint-specific User data type. You can easily achieve the result with alternative string-based syntax:
var caml =
    Camlex.Query()
        .Where(x => x["Editor"] == (DataTypes.User)"Administrator")
                .ToString();

Scenario 6. Query with sorting (OrderBy)
Suppose that you need to select all items which have ID >= 5 and the result should be sorted by Modified field:
<Where>
  <Geq>
    <FieldRef Name="ID" />
    <Value Type="Integer">5</Value>
  </Geq>
</Where>
<OrderBy>
  <FieldRef Name="Modified" />
</OrderBy>
You need to write the following Camlex expression in order to construct this query:
var caml =
    Camlex.Query()
        .Where(x => (int)x["ID"] >= 5)
        .OrderBy(x => x["Modified"]).ToString();

Scenario 7. Query with grouping (GroupBy)
Suppose that we need to select items having not-null Status field and result set should be grouped by Author field:
<Where>
  <IsNotNull>
    <FieldRef Name="Status" />
  </IsNotNull>
</Where>
<GroupBy>
  <FieldRef Name="Author" />
</GroupBy>
With Camlex you could simply rewrite it as:
var caml =
    Camlex.Query()
        .Where(x => x["Status"] != null)
        .GroupBy(x => x["Author"]).ToString();

Scenario 8. Query with non-constant expressions in lvalue and rvalue
Non-constant expression gives you more control over CAML. Suppose that you need to select items depending on current locale: for English locale you need to select items which have TitleEng field set to “eng”; for non-English locale you need to select items which have Title field set to “non-eng”. I.e.:
Query for English locale:
<Where>
  <Eq>
    <FieldRef Name="TitleEng" />
    <Value Type="Text">eng</Value>
  </Eq>
</Where>
Query for non-English locale:
<Where>
  <Eq>
    <FieldRef Name="Title" />
    <Value Type="Text">non-eng</Value>
  </Eq>
</Where>
It is not so hard with Camlex:
bool isEng = true; // or false depending on Thread.CurrentThread.CurrentUICulture

var caml =
    Camlex.Query()
        .Where(x => (string)x[isEng ? "TitleEng" : "Title"] == (isEng ? "eng" : "non-eng")).ToString();

Scenario 9. Dynamic filtering conditions
Starting with 2.0 version you can build dynamic filtering conditions and join them using WhereAll/WhereAny methods which use And/Or logical joins respectively.
Suppose that we need to retrieve all items which contain at least one of the values {“hello”, “greeting”, “hi”} in Title field. I.e. we need to use the following CAML query:
<Where>
  <Or>
    <Or>
      <Contains>
        <FieldRef Name="Title" />
        <Value Type="Text">hello</Value>
      </Contains>
      <Contains>
        <FieldRef Name="Title" />
        <Value Type="Text">greeting</Value>
      </Contains>
    </Or>
    <Contains>
      <FieldRef Name="Title" />
      <Value Type="Text">hi</Value>
    </Contains>
  </Or>
</Where>
With Camlex.NET 2.0 we can create lambda expression for each condition and pass them into new WhereAny method:
// list of tokens
var tokens = new List<string> { "hello", "greeting", "hi" };
var expressions = new List<Expression<Func<SPListItem, bool>>>();

// create lambda expression for each token in list
foreach (string t in tokens)
{
    string token = t;
   expressions.Add(x => ((string)x["Title"]).Contains(token));
}

// prepare query
var caml = Camlex.Query().WhereAny(expressions).ToString();
Note: in the example above it is important to create local variable "string token" inside loop body and assign current token to it. Without it resulting query will use only last token for all conditions. This is because of lazy expressions implementation in .Net 3.5. See the following discussion: https://camlex.codeplex.com/discussions/250635.

Last edited Oct 23, 2013 at 9:26 AM by sadomovalex, version 37