ToString() and Parse() - readable criteria

26 April 2006

I believe it’s not yet common knowledge that the two methods ToString() and Parse() of the CriteriaOperator form a pair that can be used to convert whole hierarchies of criteria to and from a string representation. This can be pretty useful in many situations, but let’s first look at an example. Here’s a line of code from my recent Advanced queries post:

view.AddProperty("OrderValue",
  "Entries.Sum(iif(RebatePercent == 0, ArticlePrice, ArticlePrice - (ArticlePrice * RebatePercent / 100)) * ArticleCount)");

In this case, the fact that the CriteriaOperator.Parse() method is used behind the scenes is not visible, but that’s exactly what happens. The complete criteria returned by the Parse() method could be created from code like this, in the same context of adding a property to a view:

view.AddProperty("OrderValue", 
  new AggregateOperand(new OperandProperty("Entries"), 
    new BinaryOperator(
      new FunctionOperator(FunctionOperatorType.Iif,
        new BinaryOperator("RebatePercent", 0, BinaryOperatorType.Equal),
        new OperandProperty("ArticlePrice"),
        new BinaryOperator(
          new OperandProperty("ArticlePrice"), 
          new BinaryOperator(
            new BinaryOperator(
              new OperandProperty("ArticlePrice"), 
              new OperandProperty("RebatePercent"), 
              BinaryOperatorType.Multiply),
            new OperandValue(100), 
            BinaryOperatorType.Divide),
          BinaryOperatorType.Minus)), 
      new OperandProperty("ArticleCount"),
    BinaryOperatorType.Multiply),
  Aggregate.Sum, null));

So, to make this clear: for every CriteriaOperator derived class, it is true that if it is converted into its string representation using the ToString() method, and the string is then converted back using CriteriaOperator.Parse(), the same CriteriaOperator derived class will result. That includes all “child criteria”, i.e. the complete hierarchy starting from the operator on which ToString() was called.

The syntax of the string representation is largely based on the specification for OPath, which Microsoft made available when ObjectSpaces was still to become part of their .NET 2 release. The specification is no longer available from Microsoft AFAIK, but a copy is available here. For specific syntax questions, the best way is to just create a CriteriaOperator of a certain type in code and then use the ToString() method on it.

Just a note: As usual, when reading database queries from external sources you should be extremely careful about the origin. If there’s a chance that criteria might be manipulated before you load them into your application and use them, this can be a very big security problem.

And a second note: Obviously there’s a performance overhead associated with the process of parsing the criteria from strings. This is certainly not relevant for one or a few criteria, but you should give this some thought in situations where you use criteria in loops – pre-parsing criteria for later use is easily done and can be a major performance advantage.

Tags
2 comment(s)
Miha Markic
You forgot to mention the complete lack of strong typing and compiler error checking (the later is even worse in the first example).
I hope you'll jump on XpoLinq wagon soon...
30 April, 2006
eXpress App Framework Team

This is post no. 3 in the mini series "10 exciting things to know about XAF". You can find

22 May, 2008

Please login or register to post comments.