expression-utils icon indicating copy to clipboard operation
expression-utils copied to clipboard

PartialEvaluation is not strict about .Value

Open devhl-labs opened this issue 5 years ago • 2 comments

Trying to use PartialEvaluator.PartialEvalBody(where, ExpressionInterpreter.Instance); to remove the closure from u => u.UserID.Value > 1 where UserID is a ulong? produces the following error:

 ---> Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Operator '>' cannot be applied to operands of type 'int' and 'ulong'
   at CallSite.Target(Closure , CallSite , Object , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.ExpressionInterpretationVisitor.uncheckedConvert(Object original, Type target)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.ExpressionInterpretationVisitor.GetResultFromUnary(UnaryExpression exp)
   at MiaPlaza.ExpressionUtils.ExpressionResultVisitor`1.DispatchVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at MiaPlaza.ExpressionUtils.ExpressionResultVisitor`1.GetResultFromExpression(Expression expression)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.ExpressionInterpretationVisitor.GetResultFromExpression(Expression exp)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.ExpressionInterpretationVisitor.GetResultFromUnary(UnaryExpression exp)
   at MiaPlaza.ExpressionUtils.ExpressionResultVisitor`1.DispatchVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at MiaPlaza.ExpressionUtils.ExpressionResultVisitor`1.GetResultFromExpression(Expression expression)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.ExpressionInterpretationVisitor.GetResultFromExpression(Expression exp)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.Interpret(Expression exp)
   --- End of inner exception stack trace ---
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.Interpret(Expression exp)
   at MiaPlaza.ExpressionUtils.Evaluating.ExpressionInterpreter.MiaPlaza.ExpressionUtils.Evaluating.IExpressionEvaluator.Evaluate(Expression unparametrizedExpression)
   at MiaPlaza.ExpressionUtils.PartialEvaluator.SubtreeEvaluator.Visit(Expression exp)).Invoke()```

devhl-labs avatar Jan 12 '20 20:01 devhl-labs

Oh I didn't have .Value

devhl-labs avatar Jan 12 '20 20:01 devhl-labs

While testing my library I found that this library does not always require the .Value to be there when working with nullable types. It would be nice if it were more consistent. I understand if it's more trouble than it's worth.

edit- In the where method below, the first thing I do is

where = PartialEvaluator.PartialEvalBody(where, ExpressionInterpreter.Instance);
// this works
var g = await Postgres.Select<UserModel>().Where(u => u.UserID > a.UserID && u.UserNames == i.UserNames).QueryAsync();

// this only works with .Value on u.UserID
var j = await Postgres.Select<UserModel>().Where(u => (u.UserID == 1 && u.UserNames == i.UserNames) || u.UserType > UserType.User).QueryAsync();

devhl-labs avatar Jan 17 '20 00:01 devhl-labs