Evaluating expressions
-
Hi I am looking for a way to evaluate expression. An expression return exacly one result. The result may be a boolean, a number value a string, etc. The idea is I give my user a tool to define expression. The expression is built in MSSQL style, and can use SQL functions. For example: $Num1 > 100 AND $Num2 < 0 At run time my program replaces the variables with values, for example: 101 > 100 and 1<0 In the past, my application ran on the server. I used SQL itself for that: I passed it the string, received the return value and it was great. No I am writing a client-server application, and this code runs on the client. So I cannot go to the server all the time. Is there a way/class/object I can pass there expressions to on the client? I was thinking of using a dataset, but I can only see it can select records from a given data table. I cannot find how to perform such calculations. Thank you!
-
Hi I am looking for a way to evaluate expression. An expression return exacly one result. The result may be a boolean, a number value a string, etc. The idea is I give my user a tool to define expression. The expression is built in MSSQL style, and can use SQL functions. For example: $Num1 > 100 AND $Num2 < 0 At run time my program replaces the variables with values, for example: 101 > 100 and 1<0 In the past, my application ran on the server. I used SQL itself for that: I passed it the string, received the return value and it was great. No I am writing a client-server application, and this code runs on the client. So I cannot go to the server all the time. Is there a way/class/object I can pass there expressions to on the client? I was thinking of using a dataset, but I can only see it can select records from a given data table. I cannot find how to perform such calculations. Thank you!
I think your options are several. You can write your own parser and evaluator from scratch (I don't know your background, but you can look up recursive-descent parsing, the "Little Language" pattern, etc. for easy starters); use a code-emitting approach like the one in this Code Project article; or use a tool like YACC or JavaCC. I haven't taken the time to do a search, but I'm sure there's something similar to the last one out there for .NET, and if not, it would be a fun port to do. I've also used database engines for this kind of stuff in the past, but I think if you can do it directly, it would be a much better approach. I was kind of iffy on the idea before I wrote my first small parser a long time ago, but it's really not a very big deal. Of course, I don't know how in-depth your evaluation requirements are, but I imagine they can't be all that intense if you were using something like SQL Server in the past. .NET also has VBScript and JScript support; both of these scripting languages have built-in expression evaluation (check out the "eval" function in JScript). If you can call that stuff, you're probably golden. Regards, Jeff Varszegi
-
I think your options are several. You can write your own parser and evaluator from scratch (I don't know your background, but you can look up recursive-descent parsing, the "Little Language" pattern, etc. for easy starters); use a code-emitting approach like the one in this Code Project article; or use a tool like YACC or JavaCC. I haven't taken the time to do a search, but I'm sure there's something similar to the last one out there for .NET, and if not, it would be a fun port to do. I've also used database engines for this kind of stuff in the past, but I think if you can do it directly, it would be a much better approach. I was kind of iffy on the idea before I wrote my first small parser a long time ago, but it's really not a very big deal. Of course, I don't know how in-depth your evaluation requirements are, but I imagine they can't be all that intense if you were using something like SQL Server in the past. .NET also has VBScript and JScript support; both of these scripting languages have built-in expression evaluation (check out the "eval" function in JScript). If you can call that stuff, you're probably golden. Regards, Jeff Varszegi
Thanks Jeff. I found something usefull in the MSDN: DataTable.Compute() and DataColumn.Expression() DataSet myData = new DataSet(); // myData.Tables.Add("Orders"); myData.Tables["Orders"].Columns.Add("ParentID", typeof(int)); myData.Tables["Orders"].Columns.Add("Exp", typeof(string)); myData.Tables["Orders"].Columns.Add("Exp2", typeof(string)); myData.Tables["Orders"].Columns["Exp"].Expression = "substring('abcdefg',2,3)"; myData.Tables["Orders"].Columns["Exp2"].Expression = "IIF(1=2,'A',iif(3>4,'B','C'))"; myData.Tables["Orders"].Rows.Add(new object[1] {123}); DataTable myTable; myTable = myData.Tables["Orders"]; // Declare an object variable. object objSum; objSum = myTable.Compute("substring('123456',3,2)", null); MessageBox.Show(objSum.ToString() + "\n" + myTable.Rows[0][1].ToString() + "\n" + myTable.Rows[0][2].ToString() );
-
Thanks Jeff. I found something usefull in the MSDN: DataTable.Compute() and DataColumn.Expression() DataSet myData = new DataSet(); // myData.Tables.Add("Orders"); myData.Tables["Orders"].Columns.Add("ParentID", typeof(int)); myData.Tables["Orders"].Columns.Add("Exp", typeof(string)); myData.Tables["Orders"].Columns.Add("Exp2", typeof(string)); myData.Tables["Orders"].Columns["Exp"].Expression = "substring('abcdefg',2,3)"; myData.Tables["Orders"].Columns["Exp2"].Expression = "IIF(1=2,'A',iif(3>4,'B','C'))"; myData.Tables["Orders"].Rows.Add(new object[1] {123}); DataTable myTable; myTable = myData.Tables["Orders"]; // Declare an object variable. object objSum; objSum = myTable.Compute("substring('123456',3,2)", null); MessageBox.Show(objSum.ToString() + "\n" + myTable.Rows[0][1].ToString() + "\n" + myTable.Rows[0][2].ToString() );
Hey, that's pretty cool. You should write an article on it! Wish I could've gotten that JScript call working-- I tried for about half an hour and gave up in disgust. You'd think they would've put a simple expression evaluator in the base class library, eh? I wrapped it up in a little class for you-- I may use this code myself on a project:
public sealed class Evaluator { private static System.Data.DataTable table = new System.Data.DataTable("dummy"); private Evaluator() {} public static object Evaluate(string _expression) { if (_expression == null) { throw new ArgumentNullException(); } return table.Compute(_expression, null); } }
Note that this simple implementation will simply throw any exception encountered when callingCompute
on theDataTable
, but I figured that that was desirable behavior. Regards, Jeff Varszegi -
Hi I am looking for a way to evaluate expression. An expression return exacly one result. The result may be a boolean, a number value a string, etc. The idea is I give my user a tool to define expression. The expression is built in MSSQL style, and can use SQL functions. For example: $Num1 > 100 AND $Num2 < 0 At run time my program replaces the variables with values, for example: 101 > 100 and 1<0 In the past, my application ran on the server. I used SQL itself for that: I passed it the string, received the return value and it was great. No I am writing a client-server application, and this code runs on the client. So I cannot go to the server all the time. Is there a way/class/object I can pass there expressions to on the client? I was thinking of using a dataset, but I can only see it can select records from a given data table. I cannot find how to perform such calculations. Thank you!
I just noticed this article on using the JScript.NET eval function in C#. Regards, Jeff Varszegi
-
Hey, that's pretty cool. You should write an article on it! Wish I could've gotten that JScript call working-- I tried for about half an hour and gave up in disgust. You'd think they would've put a simple expression evaluator in the base class library, eh? I wrapped it up in a little class for you-- I may use this code myself on a project:
public sealed class Evaluator { private static System.Data.DataTable table = new System.Data.DataTable("dummy"); private Evaluator() {} public static object Evaluate(string _expression) { if (_expression == null) { throw new ArgumentNullException(); } return table.Compute(_expression, null); } }
Note that this simple implementation will simply throw any exception encountered when callingCompute
on theDataTable
, but I figured that that was desirable behavior. Regards, Jeff Varszegi -
Hi I am looking for a way to evaluate expression. An expression return exacly one result. The result may be a boolean, a number value a string, etc. The idea is I give my user a tool to define expression. The expression is built in MSSQL style, and can use SQL functions. For example: $Num1 > 100 AND $Num2 < 0 At run time my program replaces the variables with values, for example: 101 > 100 and 1<0 In the past, my application ran on the server. I used SQL itself for that: I passed it the string, received the return value and it was great. No I am writing a client-server application, and this code runs on the client. So I cannot go to the server all the time. Is there a way/class/object I can pass there expressions to on the client? I was thinking of using a dataset, but I can only see it can select records from a given data table. I cannot find how to perform such calculations. Thank you!
Another way is through
DataSet
s. These are disconnected recordsets you could get from the SQL Server/MSDE (or whatever data provider, so long as it has either an OLE DB provider or classes designed specifically for it using ADO.NET) using aDataAdapter
orDataReader
(the latter would force you to fill theDataSet
yourself). Using aDataView
on aDataTable
lets your sort and filter using SQL-like expressions (some simple and aggregate functions are supported, too). See the documentation for theDataView
in the .NET Framework SDK for more information. Also, if you plan on displaying these in aDataGrid
, you can also use expressions in the columns.Microsoft MVP, Visual C# My Articles