ExpressionTree重写 - 导航属性的MakeMemberAccess()

Smu*_*202 2 c# expression-trees .net-3.5

前一个问题隐约有关

:我使用的ExpressionTree游客的衍生物作为解释这里

在我的VisitMemberAccess方法中,我目前使用以下内容创建MemberExpressions:

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

在大多数情况下,这是有效的.

鉴于一些测试类......

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; }
}
Run Code Online (Sandbox Code Playgroud)

代码将正确映射(EntityA x) => x.Id(EntityB x) => x.MyId哪个是伟大的,并且工作可爱.引入导航属性时出现问题:

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

public class EntityBDetails
{
    public string MyName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

鉴于上述微不足道的案例,我想(EntityA x) x => x.Name映射到(EntityB x) x => x.NavigationProperty.Name.还有问题,我不知道要提供什么来MakeMemberAccess使这项工作...我可以比较mapping.TargetMemberInfo.DeclaringType == mapping.TargetMemberInfo.ReflectedType以确定是否涉及导航属性,但我如何创建必要的MemberExpression?

提前致谢!

注意:我正在研究的代码库是VB; C#倾向于在S​​O上获得更好/更快的答案,所以我手动转换.如果我做了愚蠢的拼写错误/等等,请告诉我

svi*_*ick 10

我认为它可以帮助将C#代码翻译成英文,然后将其转换为表达式创建代码:

表达x.NavigationProperty.Name其实就是"访问属性NavigationPropertyx,然后访问财产Name上的结果.现在,代码:

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);
Run Code Online (Sandbox Code Playgroud)

  • 我并没有嘲笑的意思。看起来您没有明白必须使用“MakeMemberAccess()”两次,因为您要创建的表达式中有两个属性访问。我知道你知道这个表达式的作用。但我认为通过将 C# 翻译成英语,停下来思考它的实际含义可能会很有用。我没有对命名发表评论,所以我不确定你为什么提到它。 (3认同)