Wednesday, June 13, 2012

Camlex.Net 3.2: add expressions to existing string queries

About half year ago we added non-trivial feature to the Camlex: reverse engineering. Details can be found here: Camlex.NET became bidirectional and goes online. Version 3.0 is released. Briefly it allows to parse existing string query into expression tree. Based on this feature we ran online service: http://camlex-online.org where you can paste string CAML query and see how it looks like with Camlex syntax.

When worked over reverse engineering, I thought that there may be many interesting applications. Today I released version 3.2 with another feature built on top of reverse engineering which is closer to applied development. Now you may pass existing string query to the Camlex and add more conditions via lambdas. I.e. you may use Camlex with tools which work with plain CAML queries, expand them using Camlex syntax and pass back to that tool.

Let’s see example. Suppose that we have a CAML query:

   1: <Where>
   2:   <Eq>
   3:     <FieldRef Name="Title" />
   4:     <Value Type="Text">test</Value>
   5:   </Eq>
   6: </Where>

it will return list items which have Title = “test”. We need to add another condition: we also want to return those items which have Title = “foo”. Now we can make it like this:

   1: string existingQuery =
   2:     "   <Where>" +
   3:     "       <Eq>" +
   4:     "           <FieldRef Name=\"Title\" />" +
   5:     "           <Value Type=\"Text\">test</Value>" +
   6:     "       </Eq>" +
   7:     "   </Where>";
   8:  
   9: var query = Camlex.Query().WhereAny(existingQuery, 
  10:     x => (string)x["Title"] == "foo").ToString();

It will produce the following result:

   1: <Where>
   2:   <Or>
   3:     <Eq>
   4:       <FieldRef Name="Title" />
   5:       <Value Type="Text">foo</Value>
   6:     </Eq>
   7:     <Eq>
   8:       <FieldRef Name="Title" />
   9:       <Value Type="Text">test</Value>
  10:     </Eq>
  11:   </Or>
  12: </Where>

By the same way you may combine conditions via WhereAll method – and in CAML you will get “And” instead of “Or”. Of course you may pass complicated queries and combine several other expressions. Camlex will parse string, create resulting expression tree and returns combined CAML:

   1: string existingQuery =
   2:     "<Where>" +
   3:     "  <And>" +
   4:     "    <Eq>" +
   5:     "      <FieldRef Name=\"Title\" />" +
   6:     "      <Value Type=\"Text\">foo</Value>" +
   7:     "    </Eq>" +
   8:     "    <Eq>" +
   9:     "      <FieldRef Name=\"Title\" />" +
  10:     "      <Value Type=\"Text\">test</Value>" +
  11:     "    </Eq>" +
  12:     "  </And>" +
  13:     "</Where>";
  14:  
  15: var query = Camlex.Query().WhereAny(existingQuery,
  16:     x => (int)x["Count"] > 1 && x["Status"] != null).ToString();

will produce:

   1: <Where>
   2:   <Or>
   3:     <And>
   4:       <Gt>
   5:         <FieldRef Name="Count" />
   6:         <Value Type="Integer">1</Value>
   7:       </Gt>
   8:       <IsNotNull>
   9:         <FieldRef Name="Status" />
  10:       </IsNotNull>
  11:     </And>
  12:     <And>
  13:       <Eq>
  14:         <FieldRef Name="Title" />
  15:         <Value Type="Text">foo</Value>
  16:       </Eq>
  17:       <Eq>
  18:         <FieldRef Name="Title" />
  19:         <Value Type="Text">test</Value>
  20:       </Eq>
  21:     </And>
  22:   </Or>
  23: </Where>

By the same way you may expand OrderBy, GroupBy and ViewFields fields:

   1: string existingQuery =
   2:     "  <OrderBy>" +
   3:     "    <FieldRef Name=\"Modified\" Ascending=\"False\" />" +
   4:     "  </OrderBy>";
   5:  
   6: var query = Camlex.Query().OrderBy(existingQuery,
   7:     x => new[]{x["Title"], x["State"] as Camlex.Asc}).ToString();

it will get the following CAML:

   1: <OrderBy>
   2:   <FieldRef Name="Modified" Ascending="False" />
   3:   <FieldRef Name="Title" />
   4:   <FieldRef Name="State" Ascending="True" />
   5: </OrderBy>

This feature came from community and we also glad to hear your proposals on codeplex site. Hope new feature will be useful and will simplify your work.

2 comments:

  1. Alex thank you for your work on this do you know if the NuGet package will be updated to the latest version? I am only seeing 3.1.0.0 on the NuGet site.

    ReplyDelete
  2. hi Adam,
    thanks for reminder. I remember about that, but there were always some more urgent things. Updated it now in NuGet gallery.

    ReplyDelete