我写了一个小方法,可以从一个字符串构建一个属性选择器lambda - 类似于Dynamic LINQ所做的,以及Stack Overflow上的其他一百万个例子。
例如,根据此Expressions.PropertySelector<Type, PropertyType>("Source.Date")
,如果已编译,则返回Func
,类似于此(Type) => type.Source.Date
。
无论如何,我遇到的情况不仅是我需要选择属性,还要调用由其类型定义的方法。
例如,我想要相当于:(Type) => Type.Source.Date.ToString("Y")
。我知道我可以修改我的PropertySelector
方法来检测方法调用并构建适当的表达式,但我很好奇是否有更好的方法。
对于那些好奇我为什么需要这个:基本上它是我正在构建的实体框架支持的存储库。我有一个方法允许调用者传递lambda来表示要分组的属性。调用者自己根据用户输入构造lambda。所以我认为这样做是最好的方法。
但是,例如,如果要分组的属性是DateTime
,该怎么办?我会对其格式化的字符串进行分组。
处理这样的场景的最佳方法是什么?理想情况下,我希望调用者在动态构建表达式后对其进行修改。
答案 0 :(得分:2)
如果我理解正确,您有两个表达方式:一个来自T1
到T2
,第二个来自T2
到T3
,您希望将它们合并为一个(从T1
到T3
)。您可以使用LINQKit执行此操作:
public static Expression<Func<T1, T3>> CombineExpressions<T1, T2, T3>(
Expression<Func<T1, T2>> first, Expression<Func<T2, T3>> second)
{
Expression<Func<T1, T3>> result = x => second.Invoke(first.Invoke(x));
// I think double Expand here is necessary because of Invoke inside Invoke
return result.Expand().Expand();
}
例如:
Expression<Func<Person, DateTime>> getDateExpression =
person => person.DOB;
Expression<Func<DateTime, string>> dateFormatExpression =
date => date.ToString("Y");
Expression<Func<Person, string>> result =
CombineExpressions(getDateExpression, dateFormatExpression);
此处,result
包含表达式(Person x) => x.DOB.ToString("Y")
。
您可以动态构建一个或两个表达式,但不会改变组合的工作方式。