Click here to Skip to main content
15,888,401 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a query generator based on C# Expression Trees which I use it to feed the Where condition of a IQueryable<T> in EFCore 3.1. The mechanism is that it parses an object called FilterCriterion within which it included auto properties such as Field of type string, Value of type object, OperationExpression of type enum. In the last point of generating Expression object just before it is chained to Lambda<Func<T,bool>>, I have a method like this:

C#
private static Expression GetConstantExpressionWithProperOperatorSpecified(
   Type lastInnerType,
   MemberExpression memberExpression,
   object propertyValue,
   OperationExpression operationToCheckWith)
{
   Expression result = null;
   MethodInfo contains = null;
   switch (operationToCheckWith)
   {
      case OperationExpression.Equals:
         if (TypeHelper.GetTypeAliasName(lastInnerType) == "DateTime" || TypeHelper.GetTypeAliasName(lastInnerType) == "DateTime?")
         {
            var dateTimeVariable = Expression.Variable(lastInnerType);
            var res = Expression.Assign(dateTimeVariable, Expression.Constant(propertyValue, lastInnerType));
            result = Expression.Equal(memberExpression,  dateTimeVariable);
         }
         else
         {
            result = Expression.Equal(memberExpression, Expression.Constant(propertyValue, lastInnerType));
         }
         break;
      // ...
   }


And in the code which is the client of this method, when it reaches to the Count() method:

C#
var dbSet = ((CRMNewDbContext)_orderDbContext).Orders;
IQueryable<Order> queryable = null;
var findCriteria = (OrderFindCriteria)orderFindCriteria;
queryable = ApplyIncludes(dbSet);
var filteredQueryable = ApplyCriteriaOnQueryable(queryable, findCriteria);
filteredQueryable = ApplySortCriteria(filteredQueryable, findCriteria.Sorts);
var total = filteredQueryable.Count();


it produces the error:
Value cannot be null. (Parameter 'key')'


I would hope that it worked just like when as regular we type the expression by hand in the code like this:

C#
var rightVal = Convert.ToDateTime("2020-02-27");
orderQueryable = orderQueryable.Where(order => 
order.OrderDate == rightVal);


but it does not work.

What I have tried:

Try to convert and consider the date time as string.
Posted
Updated 28-Feb-20 8:09am
v2
Comments
Richard MacCutchan 28-Feb-20 4:13am    
The message is telling you that the key variable does not have a value. You need to provide something, even if it is zero.

1 solution

Expression.Variable is used to declare a local variable within a multi-statement block expression. You're trying to create a single-statement expression, so you can't use Variable here.

As far as I can see, you don't need to do anything different for DateTime values; just pass the value to Expression.Constant, and compare it to the member.
C#
case OperationExpression.Equals:
    result = Expression.Equal(memberExpression, Expression.Constant(propertyValue, lastInnerType));
    break;
 
Share this answer
 
Comments
behnami 3-Jun-20 10:17am    
Yes, you are right. I finally found that if the type of the DateTime in the underlying database field is changed to datetime2, it works just as it had already worked with previous version of EF.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900