Deserialization of LambdaExpression fails when trying to recreate client side DisplayClass on the server side.
See original GitHub issueI have a Client Server setup where I am trying to use Remote.Linq to transfer expression from the client to the server process and evaluate the expression on the server. I have a following simplified expression:
public class Person {
public short State { get; set; }
}
public class Client {
public BusinessLogic() {
short state = 95;
ServerCallWithFilter<Person>(p => p.State == state);
}
public ServerCallWithFilter<T>(Expression<Func<T, bool> predicate>) {
Console.WriteLine($"Predicate: {predicate}");
Remote.Linq.Expressions.LambdaExpression remoteLambda;
remoteLambda = predicate.ToRemoteLinqExpression();
Console.WriteLine($"RemoteLambda: {remoteLambda}");
// Send the predicate to the server and receive results.
}
}
When the Lambda expression is printed out it looks like this:
p => (Convert(p.State) == Convert(value(ExpressionSerialization.Program+<>c__DisplayClass1_0).state))
And the remote linq lambda looks like the following:
p => (Convert(p.State) Equal Convert(Remote.Linq.DynamicQuery.ConstantQueryArgument.state))
When the Remote.Linq LambdaExpression is passed to the server side the deserialization fails because the server side is unable to recreate the “ExpressionSerialization.Program+<>c__DisplayClass1_0” type and throws an expression.
When I change the code so the state variable is int instead of a short then Remote.Linq can replace DisplayClass with the actual value and the deserialization works on the server side:
public BusinessLogic() {
int state= 95;
ServerCallWithFilter<Person>(p => p.State == state);
}
Predicate: p => (Convert(p.State) == value(ExpressionSerialization.Program+<>c__DisplayClass1_0).state) RemoteLambda: p => (Convert(p.State) Equal New Remote.Linq.DynamicQuery.VariableQueryArgument`1System.Int32.Value)
After debugging I noticed that whenever Remote.Linq receives an expression like Convert(value(DisplayClass).member) during evaluation it stops because of the Convert expression…
I was wondering what way this should be fixed? Is this an issue with Remote.Linq or with the Aqua library?
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (4 by maintainers)
Top GitHub Comments
Actually no, what I suggested has no effect in your case. Also, if you only want to pass a predicate expression what you’re trying looks good as well. The issue looks like a shortcoming of remote.linq itself… I’ll try to have a look.
Looks like you’re trying the hard way 😉
It’s easier to use ‘RemoteQueryable.Factory.CreateQueryable<T>(…)’ like shown in the sample in the readme. This way some helpers take actions to e.g. substitute DisplayClass types.
However, to keep full control you may call ToRemoteLinq on your own and then further process the expression before sending it to the server. Have a look at the code in ‘Remote.Linq.DynamicQuery.RemoteQueryProvider<TSource>.TranslateExpression(…)’ to get a basic idea of what you might need to do.