2

我编写了一个小方法,可以从字符串构建属性选择器 lambda - 类似于 Dynamic LINQ 所做的以及 Stack Overflow 上的一百万个其他示例。

例如,给定 this Expressions.PropertySelector<Type, PropertyType>("Source.Date"),如果编译,它会返回一个Func类似于 this(Type) => type.Source.Date的 。

无论如何,我遇到了一种情况,我不仅需要选择属性,还需要调用由其类型定义的方法。

因此,例如,我想要与此等效的:(Type) => Type.Source.Date.ToString("Y"). 我知道我可能可以修改我的PropertySelector方法以检测方法调用并构建适当的表达式,但我很好奇是否有更好的方法。

对于那些好奇我为什么需要这个的人:基本上它用于我正在构建的实体框架支持的存储库。我有一个方法允许调用者传递一个 lambda 来表示要分组的属性。调用者自己根据用户输入构造 lambda。所以我认为这样做是最好的方法。

但是,例如,如果要分组的属性是DateTime. 我会对其格式化的字符串进行分组。

处理这种情况的最佳方法是什么?理想情况下,我希望调用者在动态构建表达式后对其进行修改。

4

1 回答 1

2

如果我理解正确,您有两个表达式:一个 from T1to T2,第二个 from T2toT3并且您想将它们组合成一个(from T1to 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")

您可以动态构建一个或两个表达式,它不会改变组合的工作方式。

于 2013-02-02T20:32:24.227 回答