-1

I have the following Expression tree which gives me an error when I compile the expression tree.

        string tenantId = "tst user";

        Expression<Func<MongoIdentityUser, bool>> filterToUse = t => t.IsActive == true && t.IsApproved == true;
        var expConst = Expression.Constant(tenantId);
        var paramExp = Expression.Parameter(typeof(MongoIdentityUser), "t");
        var callExp = Expression.PropertyOrField(paramExp, "TenantId");
        var equalExp = Expression.Equal(callExp,Expression.Constant(null));
        var equalExp2 = Expression.Equal(callExp, expConst);
        var conditionExp = Expression.Condition(equalExp, Expression.Constant(true), equalExp2);
        var AndExp = Expression.AndAlso(filterToUse.Body, conditionExp);

        var lambdaExp1 = Expression.Lambda<Func<MongoIdentityUser, bool>>(AndExp, paramExp);
       
        Console.WriteLine(lambdaExp1.Compile());

The generated expression is as follows

t => (((t.IsActive == True) AndAlso (t.IsApproved == True)) AndAlso IIF((t.TenantId == null), True, (t.TenantId == "tst user")))

But when I called lambdaExp1.Compile() it gives me the following error enter image description here

Haseeb Khan
  • 930
  • 3
  • 19
  • 41

2 Answers2

1

If you replace your

var paramExp = Expression.Parameter(typeof(MongoIdentityUser), "t");

with

var paramExp= filterToUse.Parameters[0];

Then it should work.

You can't reference the parameter of the Expression filterToUse as "t" (Would that instead try to capture a local scope variable called t?)

Chris F Carroll
  • 11,146
  • 3
  • 53
  • 61
0

The t parameter in filterToUse and paramExp are treated as different ones by LambdaCompiler (ParameterExpression does not override Equals and GetHashcode and is used as key in Definitions dictionary).

If you have Entity Framework Core added to your project you can use ReplacingExpressionVisitor to replace t with paramExp:

var filter = ReplacingExpressionVisitor.Replace(filterToUse.Parameters.First(), paramExp, filterToUse.Body); 
var AndExp = Expression.AndAlso(filter, conditionExp);
....

If it is not available for you, you can write your own one. Or use filterToUse.Parameters.First() (since you have only one expression to extend/combine) as your paramExp, i.e.:

var paramExp = filterToUse.Parameters.First();
Guru Stron
  • 102,774
  • 10
  • 95
  • 132