Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different Behavior than I expected #91

Open
danielscatigno-ncpc opened this issue Jul 26, 2022 · 3 comments
Open

Different Behavior than I expected #91

danielscatigno-ncpc opened this issue Jul 26, 2022 · 3 comments

Comments

@danielscatigno-ncpc
Copy link

danielscatigno-ncpc commented Jul 26, 2022

Hi this is more like a question, I have not found the answer anywhere

I'm trying to convert an Expression to string
1)

Expression<Func<ProjetoProcessamentoViewModel,bool>> exp = x=>x.IdProjeto==3;
exp.ToString(BuiltinRenderer.DynamicLinq,"C#");

The output is
""IdProjeto == 3""

And ok That is what I expected
but when I convert the value into a variable:
2)

int IdProjeto=3;

Expression<Func<ProjetoProcessamentoViewModel,bool>> exp = x=>x.IdProjeto==IdProjeto;
exp.ToString(BuiltinRenderer.DynamicLinq,"C#");

the output is:
"// @0 = IdProjeto\r\n\r\n"IdProjeto == @0""

Is there any way that the variable be converted to its value so the output is the same as example 1?

@zspitz
Copy link
Owner

zspitz commented Jul 31, 2022

The library doesn't support this behavior, because the expression tree doesn't reflect it. What should be the output of the following code?

int IdProjeto = 3;
Expression<Func<ProjetoProcessamentoViewModel, bool>> exp = x => x.IdProjeto == IdProjeto;
Console.WriteLine(exp.ToString(BuiltinRenderer.CSharp, "C#"));
IdProjeto = 5;
Console.WriteLine(exp.ToString(BuiltinRenderer.CSharp, "C#"));

Since the expression tree hasn't changed, the output should be the same both before and after the assignment.

What you might do is replace the variable with the value:

Expression<Func<Model, bool>> exp = x => x.IdProjeto == IdProjeto;
Console.WriteLine(exp.ToString(BuiltinRenderer.CSharp, "C#").Replace(" IdProjeto", " " + IdProjeto.ToString()));

@danielscatigno-ncpc
Copy link
Author

I can't do this , I'm sending the expression as an string to be parsed by Dynamic Linq (API method), I don't have the value of the variable (IdProjeto for example) in the moment that the expression is parsed

I've managed to get the variable value using something like

MemberExpression right = (MemberExpression)((BinaryExpression)where.Body).Left;
value = Expression.Lambda(right).Compile().DynamicInvoke();

But the case is that my expression can be a complex one and it's hard to find all variables values

I was also looking for a way to convert a System.Linq.Expressions.FieldExpression to a System.Linq.Expressions.ConstantExpression but I have not succeeded

@zspitz
Copy link
Owner

zspitz commented Sep 12, 2022

You can create a custom renderer and register it as described here.

In your case I would suggest writing a class that inherits from DynamicLinqWriterVisitor, providing an overriding implementation of the WriteMemberAccess method that passes in to WriteNode a ConstantExpression with the value of the variable if the MemberAccessExpression's object is a closure object (as in the base implementation).

There is a TryExtractValue extension method in ZSpitz.Util which you may find useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants