Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / SharePoint

Expand string CAML queries via lambda expressions with Camlex.Net

0.00/5 (No votes)
4 Dec 2012Ms-PL3 min read 21.5K   146  
Shows how using reverse engineering feature developers may add new conditions into string CAML queries using lambda expressions.

Expand string CAML queries via lambda expressions with Camlex.Net

Camlex.Net is the free open source library which allows to use lambda expressions for building CAML queries for SharePoint. Every developer who worked with CAML know how painful work with string CAML queries can be. You need to know many specific CAML rules for creating the query, plus you have to rebuild the whole xml tree when you need to add new condition to the existing query. Camlex addresses these problems and simplifies creation of the queries using lambda expressions. You may see some examples e.g. here: Camlex.NET for Windows SharePoint Services. Until recently Camlex could only create CAML from expressions, but starting with version 3.2 it supports expanding of the string queries as well.

In the previous article on the CodeProject (see Camlex.NET 3.0 and Camlex Online: CAML Reverse Engineering) I announced release of Camlex.Net 3.0. Starting with this version Camlex works in both directions: it may translate lambda expressions into strings and it may translate strings to lambda expressions. We called this feature reverse engineering. It may have many interesting applications of the Camlex. One of them is Camlex Online - free online service which allows developers to refactor their string queries to Camlex syntax.

Expanding of the string queries using lambda expressions is another application of the reverse engineering. As many other features the idea came from the Camlex community on the project site on the Codeplex. So what it actually means? Suppose that you have the following string query:

XML
<Where>
  <Or>
    <Contains>
      <FieldRef Name="Title" />
      <Value Type="Text">Sharepoint</Value>
    </Contains>
    <Contains>
       <FieldRef Name="Description" />
       <Value Type="Text">Sharepoint</Value>
    </Contains>
  </Or>
</Where>

It returns all documents which have "SharePoint" word either in Title or in Description field. After some point you decide that you need to only fetch approved documents from the result set of this query. In this example query is simple enough and you can rewrite it on Camlex completely:

C#
var query = Camlex.Query().Where(x => (((string)x["Title"]).Contains("Sharepoint") || 
    ((string)x["Description"]).Contains("Sharepoint")) &&
	(string)x["Status"] == SPModerationStatusType.Approved.ToString());

It will give the following CAML, which we are looking for:

XML
<Where>
  <And>
    <Or>
      <Contains>
        <FieldRef Name="Title" />
        <Value Type="Text">Sharepoint</Value>
      </Contains>
      <Contains>
        <FieldRef Name="Description" />
        <Value Type="Text">Sharepoint</Value>
      </Contains>
    </Or>
    <Eq>
      <FieldRef Name="Status" />
      <Value Type="Text">Approved</Value>
    </Eq>
  </And>
</Where>

But in real practice query may be much more complicated. Plus it may come from existing component which you don't want or event can't modify. So how Camlex may help here? Now it is possible to just pass existing string query to the Camlex as first parameter and additional condition in lambda expression as second. Camlex will do the rest:

C#
string existingQuery =
    "<Where>" +
    "  <Or>" +
    "    <Contains>" +
    "      <FieldRef Name=\"Title\" />" +
    "      <Value Type=\"Text\">Sharepoint</Value>" +
    "    </Contains>" +
    "    <Contains>" +
    "      <FieldRef Name=\"Description\" />" +
    "      <Value Type=\"Text\">Sharepoint</Value>" +
    "    </Contains>" +
    "  </Or>" +
    "</Where>";

var query = Camlex.Query().WhereAll(existingQuery, x => (string)x["Status"] == 
                  SPModerationStatusType.Approved.ToString()).ToString();

In result you will get the same CAML query which we got above. Camlex needs to know what logical operation should be used for joining string part and lambda expression part: And or Or. You specify that when select method from IQuery interface: WhereAll or WhereAny. Similar to the LINQ methods: in WhereAll And operation is used, while in WhereAny Or.

Using this technique you may also expand existing OrderBy, GroupBy, and ViewFields parts of the query. Plus you may pass IEnumerable of expressions for extending the string queries, which allows you to build them dynamically. More examples can be found here.

You can download source code and binaries from CodeProject or from CodePlex.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)