I want to dynamically generate a linq.expressions.expression statement which I can use as a filter.
Here is a sample Linq query that I'd like to convert to an Expression:
ctx.customer.where(c=>ctx.Invoice.Any(i=>i.customerId == c.id));
Here's my attempt
using System.Linq.Expressions;
var c = Expression.parameter(typeof(Customer),"c");
var i = Expression.parameter(typeof(Invoice),"i");
var rightPart= Expression.Equal(
Expression.propertyorField(i,"customerId"), Expression.propertyorfield(c,"id")
Please assist.
When I need to manually create linq expression I just make .Net create for me such expression from lambda and then I can explore its structure. For example run under debug
Expression<Func<TestObject, bool>> expression = t => t.Invoice.Any(i => i.CustomerId == t.Id);
and inspect expression variable.
I assume that LinqExpression
comes from using LinqExpression = System.Linq.Expressions.Expression;
.
There is no specific expression type for Any
, because it is not an operator or the like. Any
is a static method, so you should create a Call
expression for that.
You will need to build the expression based on the static method syntax rather than the extension method syntax:
ctx.customer.Where(c => Enumerable.Any(ctx.Invoice, i => i.customerId == c.id));
There are a lot of steps to this. Here it is in outline, because I don't have time to work out all of the steps correctly. I'm not entirely sure how to represent the fact that the c
parameter used in the inner lambda is not a parameter of that lambda, but rather of the outer lambda. In outline, you'll need to
Enumerable.Any
method.MakeGenericMethod
).ctx.Invoce
)rightPart
in your example code).var innerLambda = Expression.Lambda(rightPart, i);
)Where
(i.e., Expression.Lambda(methodCallExpression, c)
.The fourth step will vary if you want to combine boolean expressions as indicated in your comment.
I hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With