Camlex 3.2: reverse engineering CAML and adding conditions to string queries in Sharepoint using lambda expressions

    Some time ago, the next release of our open source Camlex.Net project was released . Quite interesting functionality was added to version 3.2, which I would like to talk about in this article.

    First, a few words about what Camlex is and how it helps in development. If you are working with Sharepoint, then you most likely have encountered the need to write CAML requests. CAML (Collaborative Application Markup Language) is a special language used in Sharepoint for various purposes. One of its uses is to write Sql-like queries to fetch data from sheets and document libraries. For example, in order to select all the items from the list, in the Title field of which the value is “Meeting”, and in the Description - “Sharepoint”, you need to use the following query:
    MeetingSharepoint


    If you need to add more conditions to the request, you will have to rebuild the entire Xml tree (in CAML, the And and Or elements can only have 2 operands). In addition, if you work with strings, the compiler does not help you, catching errors at the compilation stage.

    With Camlex, you can write this query using lambda expressions in C #:
    string query = Camlex.Query()
        .Where(x => (string)x["Title"] == "Meeting" && (string)x["Description"] == "Sharepoint").ToString();
    

    In addition, Camlex has many useful things for application developers. More details can be found in another article on Habré, which was published about 2 years ago, when we released the first version of the project (we are me and Vladimir Timashkov ): Using lambdas to build CAML-requests in SharePoint , as well as on my blog article tagged Camlex.Net: http://sadomovalex.blogspot.fi/search/label/Camlex.NET .

    Now directly to the topic of the post. About six months ago, we added quite non-trivial functionality to the project: CAML reverse engineering. It allows you to parse string queries and create an expression tree based on them. With the help of reverse engineering, we launched a free online servicehttp://camlex-online.org , with which you can convert CAML string requests to C # code. Those. Camlex turned out the other way around. If the details are interesting, the generation of C # code from the expression tree was done using another open-source project ExpressionToCode (though a bit dopped by us).

    Recently, we received several requests: the developers asked if it is possible to add additional conditions to existing CAML requests? The task seemed interesting to me, and given the fact that we already have reverse engineering, which is quite feasible. In version 3.2, this functionality was added. Now you can use Camlex together with tools that work with ordinary string queries, expand them with Camlex and pass the result back as a string.

    Let's see an example. Imagine that we have the following query:
    Sharepoint

    he will return us the items with the title "Sharepoint". Suppose we need to add one more condition to the request in order to also get elements with the title “Office”. Now it can be done like this:
    string query = Camlex.Query().WhereAny(existingQuery,  x => (string)x["Title"] == "Office").ToString();
    

    those. just pass the string request and the new condition as a lambda expression. The result will be as follows:
    SharepointOffice

    You can also add several conditions at once to more complex string queries. Here is a list of methods by which the IQuery interface has been extended:
    public interface IQuery
    {
        // ...
        IQuery WhereAll(string existingWhere, Expression> expression);
        IQuery WhereAll(string existingWhere, IEnumerable>> expressions);
        IQuery WhereAny(string existingWhere, Expression> expression);
        IQuery WhereAny(string existingWhere, IEnumerable>> expressions);
        IQuery OrderBy(string existingOrderBy, Expression> expr);
        IQuery OrderBy(string existingOrderBy, Expression> expr);
        IQuery OrderBy(string existingOrderBy, IEnumerable>> expressions);
        IQuery GroupBy(string existingGroupBy, Expression> expr);
        IQuery GroupBy(string existingGroupBy, Expression> expr);
    }
    

    Those. You can expand not only query conditions (WhereAll and WhereAny), but also OrderBy and GroupBy. You can also extend ViewFields, but these methods are in a different interface, because are not part of the overall call chain when constructing a query.

    Consider a more complex example. We add to the string query that we received above two conditions at once: select also elements in which the number of participants is more than 1 and the status is not empty:
    string existingQuery =
        "" +
        "  " +
        "    " +
        "      " +
        "      Sharepoint" +
        "    " +
        "    " +
        "      " +
        "      Office" +
        "    " +
        "  " +
        "";
    var query = Camlex.Query().WhereAny(existingQuery,
        x => (int)x["Participants"] > 1 && x["Status"] != null).ToString();
    

    As a result, we get:
    1SharepointOffice

    Those. Camlex takes all the work on the formation of a rather complex CAML-request for itself.

    In conclusion, I would like to say that Camlex is a project that develops from the needs of the community. If you have ideas and suggestions for adding new functionality, write them on the project website in the Discussions section . We try to answer all questions and, as far as possible, add new functionality.

    Also popular now: