I have a class, Users.
Users has a UserId property.
I have a method that looks something like this:
static IQueryable<User> FilterById(this IQueryable<User> p, Func<int, bool> sel)
{
return p.Where(m => sel(m.UserId));
}
Inevitably, when I call the function:
var users = Users.FilterById(m => m > 10);
I get the following exception:
Method ‘System.Object DynamicInvoke(System.Object[])’ has no
supported translation to SQL.
Is there any solution to this problem? How far down the rabbit hole of Expression.KillMeAndMyFamily() might I have to go?
To clarify why I’m doing this: I’m using T4 templates to autogenerate a simple repository and a system of pipes. Within the pipes, instead of writing:
new UserPipe().Where(m => m.UserId > 10 && m.UserName.Contains("oo") && m.LastName == "Wee");
I’d like to generate something like:
new UserPipe()
.UserId(m => m > 10)
.UserName(m => m.Contains("oo"))
.LastName("Wee");
Let’s take
UserIdas an example. You want to write:and want this to be the same as:
What you need to do is to take the expression tree of the first version and translate it to the second version.
So, first change the signature of
UserIdto accept an expression tree instead of a compiled lambda:Then, write a method that converts the first expression tree to the second version. Let’s have a look at the two expression trees:
Input:
Lambda uid | BinaryOp > / \ Parameter Constant uid 10Output:
Lambda user | BinaryOp > / \ Property Constant UserID 10 | Parameter userAs you can see, all you need to do is take the body of the lambda, recursively replace all occurrences of the parameter
uidwith the propertyUserIdon the parameteruserand create a new lambda expression with the transformed body and the parameteruser.You can use an ExpressionVisitor to do the replacement.