表达式树GetString结果

本文关键字:结果 GetString 表达式 | 更新日期: 2023-09-27 18:27:12

在从表达式创建查询时,我试图复制实体框架的行为,并且在使用Attribute获取模型属性时,我找到了使用ExpressionVisitor的方法

这是我目前得到的

    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);
        }
    }

我有一个属性NColumn,它指示表列中属性的真实名称,所以我用属性标记模型的属性

    public class BonusTypeX
    {
        [NColumn("BonusTypeName")]
        public string Name { get; set; }
    }

现在,当我试图得到表达式时,

    [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);
    }

我有这个

BonusTypeName.Contains(value(Payroll.Test.Administration.TestRepositorys+<>c__DisplayClass13).searchKey)

我期望得到的是

BonusTypeName。包含("圣诞节")

有什么方法可以得到表达式字符串吗?我正在使用

string a = string.Join(".", body.ToString().Split('.').Skip(1));

我认为这可能是错误的..:)

任何帮助都将不胜感激。

表达式树GetString结果

本地变量在运行时捕获在编译器生成的类中,这解释了Payroll.Test.Administration.TestRepositories+<>c__DisplayClass13).searchKey部分。要在表达式中获得生成字段的值,必须在访问表达式时显式替换它的值:

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);
    }
    if (node.Member.MemberType == MemberTypes.Field)
    {
       if (node.Expression is ConstantExpression)
       {
          var owner = ((ConstantExpression)node.Expression).Value;
          var value = Expression.Constant(((FieldInfo)node.Member).GetValue(owner));
          return value;
       }
    }
    return base.VisitMember(node);
}