2

У меня есть класс, как это:Создание дерева выражения на родительском объекте из существующего выражения для C# MongoDB драйвера разбора

public class Person 
{ 
    public string Name { get; set; } 

    public string Email { get; set; } 

    // ... 
} 

И у меня есть другой общий класс, как:

public class MyParentObject<T> 
{ 

    public T Item { get; set; } 

    // ... 
} 

У меня есть для пример выражения, как это:

Expression<Func<Person, bool>> expression = p => p.Name == "MyName" && p.Email = "[email protected]" 

Как я могу преобразовать это выражение:

Expression<Func<MyParentObject<Person>, bool>> expression = p => p.Item.Name == "MyName" && p.Item.Email = "[email protected]" 

EDIT:

Я думаю, что мой вопрос был не достаточно развиваться, я хотел бы метод, как это:

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression(Expression<Func<T, bool>> expression) 
{ 
    Expression <Func<MyParentObject<T>, bool>> result = // process... 
    // ... 
    return result; 
} 

EDIT:

Я должен создать новое дерево выражение, которое будет проанализировано тогда с помощью драйвера C# mongodb. Я не могу использовать Invoke для других методов компиляции в дереве выражений.

Я думаю, что я должен использовать ExpressionVisitor, но я не знаю, как ...

+1

Я верю, что преобразование выражения верное, у вас есть ошибка в p.Item.Email = "[email protected]", это должно быть p.Item.Email == "[email protected]", иначе опубликуйте вы получите. – Gusman

ответ

1

Вы можете использовать Expression.Invoke для того, как этот

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression) 
{ 
    Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item; 
    var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(
     Expression.Invoke(expression, item.Body), item.Parameters); 
    return result; 
} 

Update: Другой способ, который требует немного больше кода, но исключает Expression.Invoke, заключается в использовании производного класса ExpressionVisitor для замены параметра переданного выражения, подобного этому

public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression) 
{ 
    Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item; 
    var body = new ParameterExpressionReplacer { source = expression.Parameters[0], target = item.Body }.Visit(expression.Body); 
    var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(body, item.Parameters); 
    return result; 
} 

class ParameterExpressionReplacer : ExpressionVisitor 
{ 
    public ParameterExpression source; 
    public Expression target; 
    protected override Expression VisitParameter(ParameterExpression node) 
    { 
     return node == source ? target : base.VisitParameter(node); 
    } 
} 
+0

Я думаю, что я не могу использовать Expression.Invoke, потому что мое выражение затем используется C# mongodb-драйвером, который анализирует дерево выражений, чтобы преобразовать его в запрос mongo. – binard

+0

Тогда вы должны изменить вопрос. Мой ответ прекрасно охватывает его так, как сейчас. –

+0

Обновлен ответ на основе вашего редактирования. Надеюсь, это поможет. –

Смежные вопросы