I am trying to copy the behavior of the Entity Framework when creating a query from an expression, and I found a way to use ExpressionVisitor when getting a model property using Attribute
this is what i got so far
internal class NVisitor : ExpressionVisitor { private readonly ParameterExpression _parameter; private readonly Type _type; public NVisitor(Type type) { _type = type; _parameter = Expression.Parameter(type); } protected override Expression VisitParameter(ParameterExpression node) { return _parameter; } protected override Expression VisitMember(MemberExpression node) { if (node.Member.MemberType == MemberTypes.Property) { var memberName = node.Member.Name; PropertyInfo otherMember = _type.GetProperty(memberName); var ncols = node.Member.GetCustomAttributes(typeof(NColumn), true); if (ncols.Any()) { var ncol = (NColumn)ncols.First(); otherMember = _type.GetProperty(ncol.Name); } var inner = Visit(node.Expression); return Expression.Property(inner, otherMember); } return base.VisitMember(node); } }
I have an NColumn attribute that indicates the real name of the property from a table column, so I mark the model property by attribute
public class BonusTypeX { [NColumn("BonusTypeName")] public string Name { get; set; } }
now when im trying to get expression
[TestMethod] public void ExpressionTesting2() { string searchKey = "Xmas"; Expression<Func<BonusTypeX, bool>> expression = x => x.Name.Contains(searchKey); Type t = typeof(tbl_BonusType); var body = new NVisitor(t).Visit(expression.Body); string a = string.Join(".", body.ToString().Split('.').Skip(1)); Assert.AreEqual("BonusTypeName.Contains(\"Xmas\")", a); }
I got it
BonusTypeName.Contains (value (Payroll.Test.Administration.TestRepositories + <> c__DisplayClass13) .searchKey)
what i expect to get
BonusTypeName.Contains ("Christmas")
is there any method that gets an expression string? I use
string a = string.Join(".", body.ToString().Split('.').Skip(1));
which, I think, may be wrong .. :)
Any help would be appreciated.