ExpressionTree rewrite - MakeMemberAccess () para las propiedades de navegación

.net-3.5 c# expression-trees

Pregunta

Relacionado vagamente con una pregunta anterior

Nota : estoy usando un derivado del visitante ExpressionTree como se explica aquí

En mi método VisitMemberAccess actualmente creo MemberExpressions utilizando algo como:

// `mapping` is a class used to map EntityA's members to EntityB's members
return Expression.MakeMemberAccess(Visit(m.Expression), mapping.TargetMemberInfo);

En su mayor parte, esto funciona.

Dadas algunas clases de prueba ...

public class EntityA
{
    public long Id { get; set; }
    public string Name { get; set; }
}

public class EntityB
{
    public long MyId {get; set; }
    public string MyName { get; set; }
}

El código se asignará correctamente (EntityA x) => x.Id a (EntityB x) => x.MyId que es excelente y funciona de maravilla. Mi problema viene cuando introduces propiedades de navegación:

public class EntityB
{
    public long MyId {get; set; }
    public EntityBDetails NavigationProperty { get; set; }
}    

public class EntityBDetails
{
    public string MyName { get; set; }
}

Dado el caso trivial anterior, quisiera que (EntityA x) x => x.Name a (EntityB x) x => x.NavigationProperty.Name . Y, por otra parte, el problema, no tengo idea de qué suministrar a MakeMemberAccess para hacer que esto funcione ... Puedo comparar mapping.TargetMemberInfo.DeclaringType == mapping.TargetMemberInfo.ReflectedType para determinar si hay una propiedad de navegación involucrada, pero ¿cómo puedo crear la expresión de miembro necesaria?

¡Gracias por adelantado!

NB: El código base en el que estoy trabajando es VB; C # tiende a obtener respuestas mejores / más rápidas en SO, así que las he convertido a mano. Avísame si he hecho tontos typo / etc

Respuesta aceptada

Creo que podría ayudar a traducir el código C # al inglés, y luego traducirlo a un código de creación de expresiones:

La expresión x.NavigationProperty.Name realidad significa "propiedad de acceso NavigationProperty en x y luego accede a la propiedad Name en el resultado. Ahora, el código:

ParameterExpression x = …;
var navigationProperty = typeof(EntityB).GetProperty("NavigationProperty");
var name = typeof(EntityBDetails).GetProperty("Name");

var navigationPropertyAccess = Expression.MakeMemberAccess(x, navigationProperty);
var nameAccess = Expression.MakeMemberAccess(navigationPropertyAccess , name);


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow