3
Based on the following reply in: How to Convert an Expression Tree to a partial SQL query?, I’m using a class inherited from ExpressionVisitor
to try to treat some conditions in my expressions.
Example of use:
var pessoaId = 1; // dessa variável preciso trocar na expressão por parâmetro
// e retornar no dicionario o nome do parâmetro e valor do mesmo.
var expression = ((pessoa, telefones) => pessoa.Id == pessoaId);
var queryFilterParser = new QueryFilterParser();
var paramValues = queryFilterParser.Parse(expression);
And for that I have:
public class QueryFilterParser : ExpressionVisitor
{
public Dictionary<string, object> ParamValues { get; private set; }
...
protected override Expression VisitConstant(ConstantExpression constantExpression)
{
// Em: (pessoa.Id == value(GenericDAO.Tests.DAOTests+<>c__DisplayClass0).pessoaId)
// trocar value(GenericDAO.Tests.DAOTests+<>c__DisplayClass0).pessoaId por
// @pessoaId
// obter o valor e saber o nome do parâmetro para alimentar o dicionário
return base.VisitConstant(constantExpression);
}
...
}
I need to return a dictionary containing the name of a parameter and its value to the Dictionary<string, object>
. Then it is necessary to swap the term inside the expression, leaving a string in the format of an SQL parameter and get the value of ConstantExpression
.
How can this be done?
Editing:
To get the value and name of the parameter I am doing the following in the method VisitMember
:
protected override Expression VisitMember(MemberExpression memberExpression)
{
...
else if (memberExpression.Expression.NodeType == ExpressionType.Constant)
{
var name = memberExpression.Member.Name;
var constantExpression = (ConstantExpression)memberExpression.Expression;
var value = (memberExpression.Member as FieldInfo).GetValue(constantExpression.Value);
ParamValues.Add(name, value);
this.Visit(constantExpression);
return memberExpression;
}
...
}
Missing now replace the Constant within the expression by the parameter name. How to do ?
Issue 2:
Apparently this answer from Jon Skeet solves the problem, but with me it didn’t work: How to get the value of a Constantexpression which uses a local variable?.
From what I understand, return Expression.Constant("@" + name, typeof(string));
should work.
A simple expression containing {@pessoaId}
is generated but is not returned as in the example he gave the term changed.
protected override Expression VisitMember(MemberExpression memberExpression)
{
...
else if (memberExpression.Expression.NodeType == ExpressionType.Constant)
{
var name = memberExpression.Member.Name;
var constantExpression = (ConstantExpression)memberExpression.Expression;
var value = (memberExpression.Member as FieldInfo).GetValue(constantExpression.Value);
ParamValues.Add(name, value);
// pelo exemplo de Jon Skeet isso resolveria ...
return Expression.Constant("@" + name, typeof(string));
}
...
}
How can this be done?
Expression.Constant
it serves to store a constant value. The substitution made in its edition makes the original expression translate into something like(pessoa, telefones) => pessoa.Id == "@pessoaId"
.– Miguel Angelo