This is a migrated thread and some comments may be shown as answers.

Problem getting Expression from ExpressionText

15 Answers 348 Views
ExpressionEditor
This is a migrated thread and some comments may be shown as answers.
Denis Vuyka
Top achievements
Rank 1
Denis Vuyka asked on 09 Jun 2011, 09:12 AM
I have a blocking issue related to Expression persistance. If taking the very simple scenario - the user enteres expression text and it is applied against some objects or collections. Also the expression is saved somewhere and should be restored and applied during next sessions. So there's a need to turn a textual expression into the runtime Linq equivalent.

The problem is that it is impossible to turn Expression Text into expression on the fly. If I create a new instance of RadExpressionEditor, assign its "Item" and "ExpressionText" the "Expression" property value always equals to "null" (besides that syntax coloring is not working for predefined expressions until user types somethiing).

It seems that ExpressionEditor heavily relies on UI rather than underlying model as most of the expression parsing logic is being triggered by UI controls. I've performed a very quick glance with .NET Reflector and found that expression parsing is being triggered by Timer in control implementation so breaking any sequential tries to get the parsed result in code behind.

I would welcome any hack, workaround or dirty trick to make this working as it blocks the entire feature development we have purchased the Q1 2011 upgrade for.

Thanks in advance,
Denis

15 Answers, 1 is accepted

Sort by
0
Accepted
Yavor Georgiev
Telerik team
answered on 09 Jun 2011, 10:17 AM
Hi Denis Vuyka,

 We chose to use a timer because parsing the user input and creating a LINQ expression every time the ExpressionText property changed resulted in poor performance. Unfortunately, we didn't envision a scenario such as yours. However, I'll do my best to help you out.

 There are two ways you can circumvent your current problem.

 You can create a timer that will tick in 500 milliseconds and then read the value of the Expression property of the RadExpressionEditor.

 The other way is to use Telerik.Windows.Data.ExpressionTypeConverter to convert a string to a LINQ Expression. However, due to a limitation in Silverlight, the ExpressionTypeConverter cannot create a LambdaExpression, because it has no way of knowing the type of the parameter. That is why the converter returns a special NodeExpression class, which exposes a ToLambda method accepting a Type parameter. Unfortunately, NodeExpression is internal.

 There is a way, however, to create a lambda from a NodeExpression. The GridViewExpressionColumn is aware of the NodeExpression type and can work with it. What you'll need to do is this:
var converter = new Telerik.Windows.Data.ExpressionTypeConverter();
var nodeExpression = converter.ConvertFrom(null, null, "ID + 1") as Expression;
var gridView = new RadGridView { ItemsSource = Enumerable.Empty<MyBusinessObjects.MyBusinessObject>() };
var column = new GridViewExpressionColumn { Expression = nodeExpression };
gridView.Columns.Add(column);
column.CoerceValue(GridViewExpressionColumn.ExpressionProperty);
var expression = column.Expression as LambdaExpression;

 I realize that both hacks are as dirty as they come, so we will wrap the whole Converter and NodeExpression thing in a public API to make it easy to take advantage of the expression parsing engine without using any of the controls. However, as the Q2 beta is nearly upon us, this won't make it time for the beta release, but it will be there for the official Q2 drop in July.

 Please accept my apologies for any inconveniences this might have caused you. Also, please let me know if you are interested in a private build with the new public expression parser.

Best wishes,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Denis Vuyka
Top achievements
Rank 1
answered on 09 Jun 2011, 10:57 AM
Hello Yavor,
Thanks for quick response. The second option does not work for me as there's no CoerceValue method for GridViewExpressionColumn (at least public one). Without this call the "column.Expression" value is the same as output of type converter. That does not give me much as NodeExpression inherits the base Expression type and so has no "Compile" method, so I cannot compile the result and run against some other instance.

The timer-based workaround (first option) works fine for me (as I can compile the result and execute against different instances in the background). I will try to stick to this approach until new version of ExpressionEditor arrives.

Thanks,
Denis
0
Yavor Georgiev
Telerik team
answered on 09 Jun 2011, 11:46 AM
Hello Denis Vuyka,

 My apologies, the CoerceValue method under Silverlight is another internal method. What you can do is call the GetValueForItem method on the column, passing the data item you would have set to the Item property of RadExpressionEditor. This will trigger the value coercion internally and will update the Expression property of the column.

Best wishes,
Yavor Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Denis Vuyka
Top achievements
Rank 1
answered on 09 Jun 2011, 12:21 PM
Hello Yavor,

Your last suggestion works like a charm for me! I have managed to create a very simple facade to extract expressions based on plain text representation, compile them and evaluate them against other instances in the background without UI being involved. As soon as new APIs are shipped I will be able refactoring my facade code without touching anything else. 

In case someone else comes across the similar issue here's the code I'm using to deal with expressions:

  public static class ExpressionEvaluator
  {   
    public static Expression GetExpression(object instance, string expression)
    {
      var converter = new ExpressionTypeConverter();
      var nodeExpression = converter.ConvertFrom(nullnull, expression) as Expression;
      var gridView = new RadGridView { ItemsSource = GetEmptySource(instance) };
      var column = new GridViewExpressionColumn { Expression = nodeExpression };
      gridView.Columns.Add(column);
      var itemValue = column.GetValueForItem(instance);
      return column.Expression;
    }
 
    private static IEnumerable GetEmptySource(object prototype)
    {
      var listType = typeof(List<>).MakeGenericType(new[] { prototype.GetType() });
      return Activator.CreateInstance(listType) as IEnumerable;
    }
 
    public static object Execute(dynamic instance, string expression)
    {
      var expr = GetExpression(instance, expression);
      return Execute(instance, expr);
    }
    
    public static object Execute(dynamic instance, Expression expression)
    {      
      dynamic dynamicExpression = expression;
      dynamic compiledExpression = dynamicExpression.Compile();
 
      bool hasParameters = dynamicExpression.Parameters.Count > 0;
      object executionResult = hasParameters ? compiledExpression(instance) : compiledExpression();
 
      return executionResult;
    }   
  }

Regards,
Denis
0
Gareth
Top achievements
Rank 1
answered on 18 Jul 2011, 07:13 AM
Hi,

I have the same problem and was wondering where this public API is so I can use it now?
0
Yavor Georgiev
Telerik team
answered on 18 Jul 2011, 09:15 AM
Hello Gareth,

 Our Q2 2011 release brings the TryParse extension method to RadExpressionEditor. You can call it on an existing, pre-configured instance of RadExpressionEditor (meaning that it will use the Item property on the editor to infer the lambda's parameter type).

Kind regards, Yavor Georgiev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Gareth
Top achievements
Rank 1
answered on 19 Jul 2011, 07:11 AM
Hi,

Thanks for the quick reply.
I'm using the Q2 2011 release but I can't find the method you mention on the RadExpressionEditor. I'm using the Silverlight Version?Also I can't seem to find anyway in which to add custom functions to the Silverlight Version.

I have to say I think this is one of the most useful controls. I hope you continue to expand on it. It very simply gives me the ability to provide users the capability to add formulas to anything they want to customise....

Thanks and regards,

Gareth
0
Milan
Telerik team
answered on 19 Jul 2011, 08:11 AM
Hi Gareth,

The TryParse method is an extension method of RadExpressionEditor. To be able to use it simply add the Telerik.Windows.Controls namespace to your source file. 

Kind regards,
Milan
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Yavor Georgiev
Telerik team
answered on 19 Jul 2011, 09:43 AM
Hi Gareth,

 Thank you for the kind words :) We're happy when our customers are happy.

 There is a PITS item for your feature request, which you can find and track here. Don't forget to vote for it, as this increases its priority in our backlog.

Kind regards, Yavor Georgiev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Gareth
Top achievements
Rank 1
answered on 19 Jul 2011, 11:16 AM
Great, Thanks to both of you.

The extension works and I've voted for the feature :)

Cheers,
Gareth
0
Gareth
Top achievements
Rank 1
answered on 05 Sep 2011, 09:40 AM
Hi,

The ExpressionEditor is an exrtremely powerful control. As I mentioned above I'm using it to enable users to create their own formulas on certain controls to calculate values. I'm sure this is, and will be, a more and more common use. My particular scenario is that I have a application running a .net ria service web service, with a silverlight client. We are also finishing a wp7 client too - as such I have few requests for this control (if this isn't the appropriate forum, please point me to the right one):
    1. Most importantly I think it would be great if the formula engine can be seperated from the UI editor - that way users can create formulas using the UI editor (in sliverlight), and I can parse and evaluate them at any point. Most importantly it means I can evaluate them on the web services without being forced to instantiate a UI thread purely to evaluate the formula.
    2. The silverlight editor is missing a few functions the WPF one has - namely the ability to add custom formulas to the UI editor, that would be extremely useful.
    3. As we're using a wp7 app too, we desperately need to be able to evaluate formulas on the windows phone. If point 1 above was done, that would hopefuly mean we could evaluate the formulas using the engine library in wp7 too.

I realise this is quite a few requests, but I think it would create a very powerful, re-usable, formula engine across all the .net platforms . This would enable any application that permits user customisation (such as ours and many, many others) to provide a powerful formula capability to the user. Is there any chance this could be considered (especially point 1 and making the engine available to wp7?). If so where could I vote for it, and what kind of timeframe would we be looking at? If not, could you please give me an idea of the roadmap for this functionality?

Once again, thanks on a brilliant control though :)

Thanks and regards,
Gareth
0
Stefan Dobrev
Telerik team
answered on 08 Sep 2011, 07:08 AM
Hello Gareth,

Our team wants to thank you for all the kind words you have said about RadExpressionEditor. Also we are grateful for your constructive feedback about the component. Sharing it with us will make the expression editor even better control.

Now onto your questions:
  1. We do have a plan to release a separate component that will bring only the expression (calculation) engine on its own. Actually we have this implemented under the hood - this is what drives the whole expression editor. As you might expect this engine is completely decoupled from the UI (expression editor) and we just have to revise its API and make it public and officially supported .
  2. This engine has the ability to provide your own functions. We will expose this functionality in the editor as well.
  3. There is one technical limitation with formulas evaluation on the Windows Phone Runtime. Its CLR does not support Reflection.Emit API which is used in the IL generation for in-memory LINQ Expression evaluation (LambdaExpression.Compile()).The good news is that there are at least two working solutions to this problem. One is to use Mono's implementation and the other is to use Microsoft's DLR implementation of an expression interpreter.

Thanks again for your valuable feedback. It is much appreciated.

Greetings,
Stefan Dobrev
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Saulius
Top achievements
Rank 1
answered on 30 Jul 2012, 10:27 AM
Hi,

I just want to check I'm not missing something here. Initially in this thread was described scenario which I would say is common to all who use ExpressionEditor not only with RadGridView - to capture expression, convert it to string, store it for later use in db, restore it later and execute on some another object instance.

From Telerik responses I see engine is separated from UI, so why is there still no API for parsing expression on server side? Is it really so hard expose one method (OK, 2-3 methods) like  Denis Vuyka suggested? And most important without any hacks of creating UI controls on server side.

Thanks,
Saulius
0
Murray Macdonald
Top achievements
Rank 1
answered on 01 May 2015, 08:02 AM
Stefan, did this happen? The separate component that will bring only the expression (calculation) engine on its own?
0
Dimitrina
Telerik team
answered on 01 May 2015, 08:30 AM
Hi,

Thank you for your interest in RadExpressionEditor.

As it turns out, releasing a separate component to bring only the expression (calculation) engine on its own was postponed. You can refer to our online documentation on Expression Editor for further information on what is supported.

Regards,
Dimitrina
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
Tags
ExpressionEditor
Asked by
Denis Vuyka
Top achievements
Rank 1
Answers by
Yavor Georgiev
Telerik team
Denis Vuyka
Top achievements
Rank 1
Gareth
Top achievements
Rank 1
Milan
Telerik team
Stefan Dobrev
Telerik team
Saulius
Top achievements
Rank 1
Murray Macdonald
Top achievements
Rank 1
Dimitrina
Telerik team
Share this question
or