I'm trying to create dynamic queries against Entity framework (or other Linq provider).
Let me explain my problem with some sample code.
If I hardcode an expression :
var id = 12345;
Expression<Func<ItemSearch, bool>> myLambda = (s) => s.Id == id;
var finalQuery = context.ItemSearch.Where(myLambda);
this.Log((finalQuery as ObjectQuery).ToTraceString());
The generated SQL looks like this :
SELECT ...
FROM ViewItemSearch "Extent1"
WHERE "Extent1".ID = :p__linq__0
with a nice :p__linq__0
dbParameter.
If I create an expression :
var id = 12345;
ParameterExpression param = Expression.Parameter(typeof(ItemSearch), "s");
Expression prop = Expression.Property(param, "Id");
Expression val = Expression.Constant(id);
Expression searchExpr = Expression.Equal(prop, val);
Expression<Func<ItemSearch, bool>> myLambda =
Expression.Lambda<Func<ItemSearch, bool>>(searchExpr , param);
var finalQuery = context.ItemSearch.Where(myLambda);
this.Log((finalQuery as ObjectQuery).ToTraceString());
The generated SQL looks like this :
SELECT ...
FROM ViewItemSearch "Extent1"
WHERE "Extent1".ID = 12345
No more :p__linq__0
dbParameter so the Db engine cannot cache query plans.
I understand that it is because I use
Expression val = Expression.Constant(id);
But I can't figure out how to bind a variable instead of the value.
AND
logic conditions, just declare anIQueryable
and dynamically append.Where(i => yourPredicate)
. See: #11190326 If you want to applyOR
logic you will need an approach such as this: albahari.com/nutshell/predicatebuilder.aspx – Odawa