1

Closed

Dynamic queries and combining existing queries

description

First of all, thanks so much for the library. It's been immensely helpful for many projects so far, much better than dealing with CAML strings for sure.

So I'm expecting I'm doing something silly here, but here's the story anyway. Working on CAMLEX 3.3.
I've a pretty typical use case - a simple enough query with a bunch of derivatives. To reduce code, I'm using the dynamic queries syntax to add to the existing query.

So an example base query:
            var simple = CamlexNET.Camlex.Query()
                .Where(
                    p => p["Hello"] != null
                );
... and another query to combine:
            var success = CamlexNET.Camlex.Query()
                .WhereAny(
                    simple.ToString(),
                    p => p["Test"] != null
                );
                
Console.WriteLine(success.ToString());
Which gives you an output like this:
<Where>
  <Or>
    <IsNotNull>
      <FieldRef Name="Test" />
    </IsNotNull>
    <IsNotNull>
      <FieldRef Name="Hello" />
    </IsNotNull>
  </Or>
</Where>
However, this technique doesn't seem to work for more complex queries, such as the following:
            var expiryDate = "ExpiryDate";
            var commenceDate = "Commence";
            var docFolder = "DocFolder";
            var ret = CamlexNET.Camlex.Query()
                .Where(
                        p => (p[expiryDate] == null
                            || p[expiryDate] > (CamlexNET.DataTypes.DateTime)CamlexNET.Camlex.Today) &&
                            (p[commenceDate] == null
                            || p[commenceDate] <= (CamlexNET.DataTypes.DateTime)CamlexNET.Camlex.Today)
                            )
                .GroupBy(p => p[docFolder]);
Console.WriteLine(ret.ToString());
You'll see that this generates CAML XML just fine, but when you go to add to it using the same method:
var problem = CamlexNET.Camlex.Query().WhereAny(
                ret.ToString(),
                p => p["Test"] != null
            );
Console.WriteLine(problem.ToString());
The last code chunk returns a "IncorrectCamlException", siting that "Caml specified for tag 'Where' can not be translated to code". I'd suggest it's a bug in the CAML to IQuery translation, because throwing the following XML into camlex-online also fails (yet this is the CAML that is generated by the "ret" query above).
<Where>
  <And>
    <Or>
      <IsNull>
        <FieldRef Name="ExpiryDate" />
      </IsNull>
      <Gt>
        <FieldRef Name="ExpiryDate" />
        <Value Type="DateTime">
          <Today />
        </Value>
      </Gt>
    </Or>
    <Or>
      <IsNull>
        <FieldRef Name="Commence" />
      </IsNull>
      <Leq>
        <FieldRef Name="Commence" />
        <Value Type="DateTime">
          <Today />
        </Value>
      </Leq>
    </Or>
  </And>
</Where><GroupBy>
  <FieldRef Name="DocFolder" />
</GroupBy>
Closed Apr 17, 2013 at 8:06 PM by sadomovalex
hi jrath,
yes, Camlex was initially written for Sharepoint 2007, so it doesn't contains all new features, introduced in SP2010 and SP2013. I will add support for TaxonomyFieldTypeMulti to the further development list and will implement it in one of the next releases.

comments

powareverb wrote Jan 11, 2013 at 12:00 AM

Actually, sorry, you can close this. After spending more time working on this I realised the issue with the CAML -> IQuery was that "Today" won't be supported, I had to use the discussed workaround here:

[Offset Days][http://camlex.codeplex.com/discussions/270483]

and of course the conversion wouldn't know what to make of it.

sadomovalex wrote Jan 12, 2013 at 10:57 AM

hello powareverb,
the discussion which you mentioned says that OffsetDays is not supported yet. "Today" keyword is already supported (and you already use it in your code), so I think that issue is valid. I will check why it is not translated to Caml correctly.

jrath wrote Apr 17, 2013 at 6:31 AM

I've got the same Problem using Camlex.NET, Version=3.4.0.0, Culture=neutral, PublicKeyToken=831792d54d5285b7:

I want to combine the following queryString with another expression

string queryString (also created with camlex and taxonomy workaround):
<Where>
  <And>
    <Or>
      <Eq>
        <FieldRef Name="ContentType" />
        <Value Type="Text">ct1</Value>
      </Eq>
      <Eq>
        <FieldRef Name="ContentType" />
        <Value Type="Text">ct2</Value>
      </Eq>
    </Or>
    <Or>
      <Or>
        <Or>
          <Or>
            <Or>
              <Or>
                <Or>
                  <Eq>
                    <FieldRef Name="DocumentType" />
                    <Value Type="TaxonomyFieldTypeMulti">docType1</Value>
                  </Eq>
                  <Eq>
                    <FieldRef Name="DocumentType" />
                    <Value Type="TaxonomyFieldTypeMulti">docType2</Value>
                  </Eq>
                </Or>
                <Eq>
                  <FieldRef Name="DocumentType" />
                  <Value Type="TaxonomyFieldTypeMulti">docType3</Value>
                </Eq>
              </Or>
              <Eq>
                <FieldRef Name="DocumentType" />
                <Value Type="TaxonomyFieldTypeMulti">docType4</Value>
              </Eq>
            </Or>
            <Eq>
              <FieldRef Name="DocumentType" />
              <Value Type="TaxonomyFieldTypeMulti">docType5</Value>
            </Eq>
          </Or>
          <Eq>
            <FieldRef Name="DocumentType" />
            <Value Type="TaxonomyFieldTypeMulti">docType6</Value>
          </Eq>
        </Or>
        <Eq>
          <FieldRef Name="DocumentType" />
          <Value Type="TaxonomyFieldTypeMulti"></Value>
        </Eq>
      </Or>
      <IsNull>
        <FieldRef Name="DocumentType" />
      </IsNull>
    </Or>
  </And>
</Where>
Code to combine:
Camlex.Query().WhereAll(queryString, i => (string)i[categoryFieldInternalName] == categoryValue);
The result is a CamlexNET.IncorrectCamlException: "Caml specified for tag 'Where' can not be translated to code"
StackTrace:
   at CamlexNET.Impl.ReverseEngeneering.Caml.ReTranslatorFromCaml.translateWhere(IReAnalyzer analyzer, String tag)
   at CamlexNET.Impl.Query.getWhereExpressionFromString(String existingWhere)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at CamlexNET.Impl.Query.WhereAll(IEnumerable`1 expressions)
   at ........... (my functions)

jrath wrote Apr 17, 2013 at 8:00 AM

I've debugged the Camlex code and found my error:

It was the "TaxonomyFieldTypeMulti". This types are not supported by Camlex and a QueryString with these types can't be processed by Camlex.

sadomovalex wrote Apr 17, 2013 at 8:06 PM

hi jrath,
yes, Camlex was initially written for Sharepoint 2007, so it doesn't contains all new features, introduced in SP2010 and SP2013. I will add support for TaxonomyFieldTypeMulti to the further development list and will implement it in one of the next releases.