Expression method for NULLIF (with Divide) - c#

I am using C# 4.5.2. I Have to call a SumDenominator method as a denominator for an Expression.Divide method:
var SumDenominatorExpression = Expression.Call(
null,
SumDenominatorMethod,
Parameter,
SumDenominatorSelector
);
then later on the actual Expression.Divide reads:
var FractionExpression = Expression.Divide(
SumNumeratorExpression,
SumDenominatorExpression
);
if the denominator's selector generates zero then the divide by zero exception is thrown. I tried to solve this by converting the Sum expression into a Nullable<> but the Divide method doesn't swallow null values. And the SQLServer (my provider) doesn't have a NULLIF function (i.e. System.Data.Entity.SqlServer.SqlFunctions) that I can wrap a Call expression around.
How to people tackle zeros in the denominator with C# Expression trees?
UPDATE
Here are the expression methods I ended up using:
Expression.Condition(
Expression.Equal(
SumDenominatorExpression,
Expression.Constant(0.0, typeof(double))
),
Expression.Constant(0.0, typeof(double)),
FractionExpression
)

It sounds like you want EF to be able to translate this expression. That restricts the kinds of patterns we can use. The following should work:
FractionExpression =
(SumDenominatorExpression == 0)
? (int?)null /*default value - pick what you want*/
: (SumNumeratorExpression / SumDenominatorExpression);
(I'm writing the expression tree as C# for typing speed.)
Since EF does not support trees that have variables you will need to use the SumDenominatorExpression expression twice. Hopefully SQL Server will optimize that and evaluate it only once.

Related

How to compute expression

Consider this code fragment;
int sum = 0;
sum = Expression.Evaluate("1+1");
where the value of sum = 2
I do have an expression that will compute values but i want that expression to be build programatically then evaluate the result. I don't have any idea what class or namespace that I will dealing with. Anyone can help me.
You could use Expression Trees:
Expression trees represent code in a tree-like data structure, where
each node is an expression, for example, a method call or a binary
operation such as x < y.
You can compile and run code represented by expression trees.
Expression Trees (C# and Visual Basic)
Expression Tree Basics
Note: This problem can be solved using System.Reflection.Emit and work directly with MSIL, but the resulting code is hard to write and read.
After a little browsing, I suggest you checkout Flee on Codeplex: Fast Lightweight Expression Evaluator :
Flee is an expression parser and evaluator for the .NET framework. It
allows you to compute the value of string expressions such as sqrt(a^2
+ b^2) at runtime. It uses a custom compiler, strongly-typed expression language, and lightweight codegen to compile expressions
directly to IL. This means that expression evaluation is extremely
fast and efficient.
You can build Expressions trees either using lambdas or by building them programatically using classes in the System.Linq.Expressions namespace.
See MSDN for more info.
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.

Very simple explanation of a Lambda Expression

I am looking for a very simple - basic - no hardcore programming mumbo jumbo, simply put a generalized overview of a Lambda Expression in layman's terms.
A lambda expression is, simply put, a re-useable expression which takes a number of arguments:
x => x + 1;
The above expression reads "for a given x, return x + 1".
In .NET, this is powerful, because it can be compiled into an anonymous delegate, a nameless function you can declare inline with your code and evaluate to get a value:
int number = 100;
Func<int, int> increment = x => x + 1;
number = increment(number); // Calls the delegate expression above.
However, the real power of a lambda expression is that it can be used to initialize an in-memory representation of the expression itself.
Expression<Func<int, int>> incrementExpression = x => x + 1;
This means that you can give that expression to something like LINQ to SQL and it can understand what the expression means, translating it into a SQL statement that has the same meaning. This is where lambdas are very different from normal methods and delegates, and normally where the confusion begins.
Lambda Expressions are inline functions that have a different syntax to regular functions.
Example Lambda Expression for squaring a number.
x => x * x
A small unnamed inline method. Is that basic enough for you? I'm not sure what you are looking for exactly.
You also said in "layman's" terms - I presume that you have some level of software development experience (so not a complete layman)
In non functional programming languages expressions (that act on variables) perform calculations and they perform those calculations once.
Lambda expressions allow you to define (in an expression) via different syntax code that can work on a list and can conceptually be considered a function.
You could simplify this to say "They let you define functions in expressions".
Does not quite get to the "why". The why is the more interesting, in my opinion. Lambda expression allow for the manipulation of functions and partial functions.

How to get a calculated value from a compiled LambdaExpression?

I'm currently working on a project at work, and we are using the Telerik RadControls for Silverlight. In their Q1 2011 release, they added a new control called the Rad Expression Editor. In the Rad Expression Editor, you can pass in an object and create formulas (or expressions), and the editor window will give you a preview of the result of the expression. I've spoken with Telerik about this and they intentionally did not expose the result of this, but mentioned that I could use LambdaExpression.Compile(). I'm very new to Linq and using Lambda Expressions in general, but started looking into this.
As an example, lets say I have an object called Finances, and in that object, there are 4 nullable decimal fields (values): Debit (10), DebitYTD (100), Credit (20) and CreditYTD (200). In the formula, I want to do something like: Debit - Credit + DebitYTD - CreditYTD.
The Telerik Rad Expression Editor will give me the expression that is generated:
ExpressionEditor.Expression = {Param_0 => ((Param_0.Debit - Param_0.Credit + Param_0.DebitYTD - Param_0.CreditYTD}
The result of this expression should be -110. I need to be able to get the value that is calculate in the expression, but have not been able to figure out how to get this number. Can anyone please explain how this can be accomplished? Thanks.
You haven't really told us much about the API which it exposes, but it sounds like you could use:
var compiled = ExpressionEditor.Expression.Compile();
var result = compiled(input);
where input is an appropriate variable of type Finances.
EDIT: Okay, as the expression isn't exposed nicely:
var typeSafe = (Expression<Func<Finance, decimal?>>) ExpressionEditor.Expression;
var compiled = typeSafe.Compile();
var result = compiled(input);
I had very similar requirements. There was a need to compile expression and evaluate at runtime against different instances. However function compilation is not so trivial as you have to know the type of the result value during compile time and in most of the cases this will be impossible: user writes "1+1" and you get System.Int32, or user writes "(1+1).ToString()" and you get System.String. I'm sure this is the point where you experience (or will experience) difficulties.
In order to solve the expression compilation problem I would recommend jumping into DLR (Dynamic Language Runtime). You will need to reference "Microsoft.CSharp" assembly for your Silverlight project. As you need just access to "Compile" method for the expression (that is already in there), it will be fair enough doing that against "dynamic" object. Here's a short sample to demonstrate that:
dynamic dynamicExpression = expressionEditor.Expression;
dynamic compiledExpression = dynamicExpression.Compile();
object executionResult = compiledExpression(myInstance);
The "executionResult" variable will hold the result of expression evaluation. Now you can do whatever you need to do with the result.
Hope that helps

Why does 'Submissions.Where(s => (false && s.Status == Convert.ToInt16("")))' raise an FormatException?

I thought the query was quite trivial, but it's raising a FormatException ("Input string was not in a correct format") nonetheless:
Submissions.Where(s => (false && s.Status == Convert.ToInt16("")))
(of course, in my code, another expression that evaluates to 'false' is located before '&&')
So why is the part after '&&' evaluated, since the first part is always false and the total expression can never evaluate to true?
The situation is particularly strange because only the Convert.ToInt16("") part seems to raise an exception - other parts of my original query of more or less the same structure, like
Submissions.Where(s => (false && s.SubmissionDate <= DateTime.Now))
are evaluated correctly.
As the others have pointed out, LINQ to SQL code gets pulled apart into an expression tree before being run as SQL code against the database. Since SQL does not necessarily follow the same short-circuit boolean rules as C#, the right side of your expression code might get parsed so that the SQL can be constructed.
From MSDN:
C# specifies short circuit semantics
based on lexical order of operands for
logical operators && and ||. SQL on
the other hand is targeted for
set-based queries and therefore
provides more freedom for the
optimizer to decide the order of
execution.
As for why you're getting an exception with this code, Convert.ToInt16("") will always throw precisely that exception because there's no way to convert an empty string into an integer. Your other example doesn't attempt an invalid conversion, hence it runs without a problem.
If Submissions is an IQueryable<T>, then this isn't a regular C# delegate, but is an expression tree. Some code (the LINQ provider) has to pull this tree apart and understand it - so if you have oddities in the expressions, then expect odd output.
Well based on your answer to my question in the comments, since it's Linq to Sql, it's not actually a delegate. I tried recreating it using Linq to Objects, and sure enough there was no issue at all. VS actually pointed out that "Unreachable code detected". Since in your case it's actually Linq to Sql, then it's building up an expression tree, in which case it has to decipher all of it and all bets are off.
Suggestion: use a static Int16 to hold the result of Convert.ToInt16(""), then refer to the static in the predicate.
Better still, do you know what the result of Convert.ToInt16("") is? Yes? Then use that instead. For instance, if it's 0, then say s.Status == 0. You could even make that a constant.

Dynamic logical expression parsing/evaluation in C# or VB?

What is the best was to evaluate an expression like the following:
(A And B) Or (A And C) Or (Not B And C)
or
(A && B) || (A && C) || (!B && C)
At runtime, I was planning on converting the above expressions to the following:
(True And False) Or (True And False) Or (Not False And True)
or
(True && False) || (True && False) || (! False && True)
Conditions:
1) The logical expression is not known until runtime.
2) The number variable and their values are not known until runtime.
3) Variable values are never null.
I know I could create a simple assemble with a class and a method that I generate at runtime based on the inputs, but is there a better way.
I have done this before. Use a string builder to write the code, then call the compiler. After that, you load the assembly and call the method.
Suggestions?
Thanks.
If you're using .NET3.5 then you can parse the text and create an abstract sytax tree using the Expression classes. Then create a suitable LambdaExpression instance and compile it into a delegate, which you can then execute.
Constructing a parser and syntax tree builder for this kind of fairly simple grammer is quite an interesting exercise, and will execute somewhat faster than invoking the compiler (and it's neater in my view as well).
If you're not using .NET3.5, then it's also not complicated to implement an interpreted abstract syntax tree yourself.
Be warned: the two final conditions you're talking about are not necessarily equivalent. The && operators in C# will use short-circuit evalution, while the logical And operator in VB does not. If you want to be sure the statements are equivalent, translate a user And to AndAlso and a user Or to OrElse.
For simple expresssions you probably won't notice a difference. But if the conditions can have side effects or if the performance difference between the two is a concern, this can be important.
You can use https://github.com/mrazekv/logicalparser
Its simply library to write logical expression (evaulated with precenednce table, allows to OR, NOT, AND operator and >, >=, <=, < on integer variables and = on string variables)
You can do this easily with:
a parser generator (like ANTLR, mentioned above) that takes boolean expressions as input and produces an infix list and
code to evaluate a Reverse Polish Notation stack.
The grammar looks something like this:
program: exprList ;
exprList: expr { Append($1); }
| expr OR exprList { Append(OR); }
| expr AND exprList { Append(AND); }
| NOT exprList { Append(NOT); }
| ( exprList ) { /* Do nothing */ }
;
expr: var { Append($1); }
| TRUE { Append(True); }
| FALSE { Append(False); }
;
To evaluate, you do this:
for each item in list
if item is symbol or truth value, push onto RPN stack
else if item is AND, push (pop() AND pop())
else if item is OR, push (pop() OR pop())
else if item is NOT, push (NOT pop())
result = pop()
For symbols, you have to substitute the truth value at runtime.
You can write a simple interpreter/parser. Use something like ANTLR and reuse existing grammars.
If you are using .NET 3.5, you can create a Lambda Expression. Then you can create a delegate from it and call as standard delegate/method.
On the internet is a lot of samples about Lambda Expressions.
One solution would be to assemble the expression as a string, and then send it SQL Server, or whatever your database is for evaluation. Replace the actual variables with 1=1 or 0=1 for True and False respectively, and you would end up with a query like this:
SELECT 1 WHERE (1=1 And 0=1) Or (1=1 And 1=1) Or (Not 0=1 And 1=1)
Then when you run the query, you get a 1 back when the result is true. May not be the most elegant solution, but it will work. A lot of people will probably advise against this, but I'm just going to throw it out there as a possible solution anyway.
This will not be the best answer, but I myself had this problem some time ago.
Here is my old code:
VB.Net - no warranty at all!
https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB
Dim BoolTermParseObjekt As New BoolTermParse
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)
This code eats a String with multiple '(', ')', 'and', 'or' plus 'other things' and breaks down the logic to a boolean by replacing the things with boolean values.
therefore:
Whatever 'other things' I wanted to evaluate I had to put in Function resolveTerm()
at the comment "'funktionen ausführen und zurückgeben, einzelwert!"
in page 2.
There the only evaluation rightnow is "If number is > 1"
Greetings
Take a look at my library, Proviant. It's a .NET Standard library using the Shunting Yard algorithm to evaluate boolean expressions.
It could also generate a truth-table for your expressions.
You could also implement your own grammar.

Categories