Rel开发者_如何转开发ated vaguely to a previous question
Note : I'm using a derivative of the ExpressionTree visitor as explained here
In my VisitMemberAccess
method I currently create MemberExpressions using something along the lines of:
// `mapping` is a class used to map EntityA's members to EntityB's members
return Expression.MakeMemberAccess(Visit(m.Expression), mapping.TargetMemberInfo);
For the most part, this works.
Given some test classes...
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; }
}
The code will correctly map (EntityA x) => x.Id
to (EntityB x) => x.MyId
which is great and works lovely. My problem comes when you introduce navigation properties:
public class EntityB
{
public long MyId {get; set; }
public EntityBDetails NavigationProperty { get; set; }
}
public class EntityBDetails
{
public string MyName { get; set; }
}
Given the above trivial case, I would want (EntityA x) x => x.Name
to map to (EntityB x) x => x.NavigationProperty.Name
. And therelies the problem, I have no idea what to supply to MakeMemberAccess
to make this work... I can compare mapping.TargetMemberInfo.DeclaringType == mapping.TargetMemberInfo.ReflectedType
to determine whether there is a navigation property involved, but how do I create the necessary MemberExpression?
Thanks in advance!
NB: The code base I'm working on is VB; C# tends to get better/faster answers on SO so I've converted by hand. Let me know if I've made silly typo's/etc
I think it could help to translate the C# code into English, and then translate that into an expression-creating code:
The expression x.NavigationProperty.Name
actually means “access property NavigationProperty
on x
and then access property Name
on the result. Now, the code:
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);
精彩评论