给出以下课程
public class Person
{
public string Name { get; }
public List<Person> Friends { get; }
}
我正在寻找一种方法来获取以下字符串“Friends.Name”,当使用表达式&gt;时。
以下是我想要做的伪代码:
Expression<Func<Person,string>> exp = x => x.Friends.Name
由于显而易见的原因而无法编译。
我怎样才能实现这一目标?即使你没有代码,一般的方法也可以解决问题,因为我缺乏这方面的灵感。
由于
答案 0 :(得分:4)
使用这种表达方式,你无法得到你想要的东西:
Expression<Func<Person,string>>
因为Person
的集合为Friends
。实际上,Func
的返回类型并不重要。这将有效:
static string GetPath(Expression<Func<Person, object>> expr)
{
var selectMethodCall = (MethodCallExpression)expr.Body;
var collectionProperty = (MemberExpression)selectMethodCall.Arguments[0];
var collectionItemSelector = (LambdaExpression)selectMethodCall.Arguments[1];
var collectionItemProperty = (MemberExpression)collectionItemSelector.Body;
return $"{collectionProperty.Member.Name}.{collectionItemProperty.Member.Name}";
}
用法:
var path = GetPath(_ => _.Friends.Select(f => f.Name)); // Friends.Name
但这是一个相当简单的案例,而在我看来,您正在从实体框架中执行类似Include
方法的操作。
所以,如果你想解析更复杂的表达式,比如:
_ => _.Friends.Select(f => f.Children.Select(c => c.Age))
你需要以更通用的方式探索表达。
答案 1 :(得分:0)
假设下面是exoression,你可以得到这样的道路:
Expression<Func<Person, string>> exp = x => x.Name;
var lambdaBody = exp.Body;
if(lambdaBody.NodeType == ExpressionType.MemberAccess)
{
var memberExpression = lambdaBody as MemberExpression;
Console.WriteLine(memberExpression.ToString());
}
输出:
x.Name