Я пытаюсь изменить выражение MemberBinding с помощью посетителя Expression. Но я получаю сообщение об ошибке, когда пытаюсь скомпилировать модифицированное выражение, которое говорит:
'переменная' источник 'типа' EFTest.Views.TestView 'ссылка из области видимости' ', но она не определена'
Я также хотел бы отметить, что я не получаю никакой ошибки, если я возвращаю MemberBinding, как в функции VisitMemberBinding. Я также убедился, что модифицированное выражение точно такое же, как оригинальное.
Конечной целью этой работы будет блокирование определенного столбца во всех запросах linq в EntityFramework Core. Пожалуйста, дайте мне знать, если у вас есть предложения по этому поводу.
Примеры кодов ниже
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; }
}