修改动态属性选择器Lambda

时间:2013-02-02 14:08:59

标签: c# .net entity-framework lambda expression-trees

我写了一个小方法,可以从一个字符串构建一个属性选择器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,该怎么办?我会对其格式化的字符串进行分组。

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

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您有两个表达方式:一个来自T1T2,第二个来自T2T3,您希望将它们合并为一个(从T1T3)。您可以使用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")

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

相关问题