如何使用Expression Visitor修改MemberBinding表达式

时间:2018-11-07 06:40:24

标签: c# linq entity-framework-core linq-expressions expressionvisitor

我正在尝试使用表达式访问者修改MemberBinding表达式。但是当我尝试编译表示以下内容的修改表达式时出现错误:

从范围”引用的类型为'EFTest.Views.TestView'的变量'source',但未定义'

我还要提及的是,如果我返回VisitingMemberBinding函数中的MemberBinding,则不会出现任何错误。我还确保修改后的表达式与原始表达式完全相同。

这项工作的最终目的是阻止EntityFramework Core中所有linq查询中的特定列。如果您对此有任何建议,请告诉我。

示例代码如下

class Expre
{
    static void Main(string[] args)
    {
        DataContext context = new DataContext();

        var rs = context.Query<TestView>().Select(m => new MyModel()
        {
            Id = m.DocumentId,
        });

        Visitor visitor = new Visitor();
        var ss = visitor.Modify(rs.Expression);
        var CompiledLambdaExpression = Expression.Lambda(ss).Compile();

        EntityQueryable<MyModel> queryAble = (EntityQueryable<MyModel>)CompiledLambdaExpression.DynamicInvoke();
        var rss = Enumerable.ToList(queryAble);

    }
}

public class Visitor : ExpressionVisitor
{
    public MemberBinding MemberBinding;
    public Expression Modify(Expression expression)
    {
        var r = Visit(expression);
        return r;
    }

    protected override MemberBinding VisitMemberBinding(MemberBinding node)
    {
        Type targetType = typeof(MyModel);
        Type sourceType = typeof(TestView);

        PropertyInfo SourceProperty = sourceType.GetProperty("DocumentId");
        PropertyInfo TargetProperty = targetType.GetProperty("Id");

        ParameterExpression parameterExpression = Expression.Parameter(sourceType, "m");

        MemberExpression propertyExpression = Expression.Property(parameterExpression, SourceProperty);
        MemberBinding memberBinding = Expression.Bind(TargetProperty, propertyExpression);

        return base.VisitMemberBinding(memberBinding);
    }
    protected override Expression VisitParameter(ParameterExpression node)
    {
        return base.VisitParameter(node);
    }
}
public class MyModel
{
    public Int32 Id { get; set; }
    public string Name { get; set; }
}
public class TestView 
{
    public Int32 Code { get; set; }
    public string LanguageCode { get; set; }
    public Int32 DocumentId { get; set; }
}

0 个答案:

没有答案