我怎么能从这个lambda表达式中提取成员路径

时间:2010-09-17 18:42:26

标签: .net linq lambda

我有一个方法可以为我的linq查询添加日期条件。我想要做的是将x.Due作为参数传递给它,使其能够适用于任何日期。任何想法?

protected virtual IQueryable<TaskView> AddTaskDuePredicate( DateCriteria dateCriterion, IQueryable<TaskView> taskSummary )
{
        if ( dateCriterion.Condition == DateCondition.LessThan )
            taskSummary = taskSummary.Where( x => x.Due < dateCriterion.Value1 );
        else if ( dateCriterion.Condition == DateCondition.LessThanOrEqualTo )
            taskSummary = taskSummary.Where( x => x.Due <= dateCriterion.Value1 );
        else if ( dateCriterion.Condition == DateCondition.GreaterThan )
            taskSummary = taskSummary.Where( x => x.Due > dateCriterion.Value1 );
        else if ( dateCriterion.Condition == DateCondition.GreaterThanOrEqualTo )
            taskSummary = taskSummary.Where( x => x.Due >= dateCriterion.Value1 );
        else if ( dateCriterion.Condition == DateCondition.EqualTo )
            taskSummary = taskSummary.Where( x => x.Due == dateCriterion.Value1 );
        else if ( dateCriterion.Condition == DateCondition.Between )
            taskSummary = taskSummary.Where( x => x.Due <= dateCriterion.Value1 && x.Due >= dateCriterion.Value2 );

    return taskSummary;
}

2 个答案:

答案 0 :(得分:1)

您必须将lambda表达式作为表达式树,如下所示:

protected virtual IQueryable<TaskView> AddTaskDuePredicate(
    Expression<Func<TaskView, DateTime>> projection,
    DateCriteria dateCriterion,
    IQueryable<TaskView> taskSummary)

然后,您必须使用Expression<Func<TaskView, bool>>Expression.GreaterThan等内容从该投影中构建Expression.Lambda。在我的头顶:

ParameterExpression p = projection.Parameters[0];
Expression constant = Expression.Constant(dateCriterion.Value1);
Expression comparison = Expression.GreaterThan(projection.Body, constant);
Expression lambda = Expression.Lambda<Func<TaskView, bool>>
    (comparison, p);
taskSummary = taskSummary.Where(lambda);

完全未经测试。显然,一旦你为GreaterThan工作,其余的应该相对容易...

答案 1 :(得分:0)

这是我最终的结果。 我可以将此方法称为.Where()参数 所以,

taskSummary.Where( AddDatePredicate<TaskView>( x => ( DateTime )x.Due, filterInfo.Due ) );

        protected virtual Expression<Func<T, bool>> AddDatePredicate<T>( Expression<Func<T, DateTime>> projection, DateCriteria dateCriterion)
        {
            ParameterExpression p = projection.Parameters[ 0 ];
            Expression constant = Expression.Constant( (DateTime)dateCriterion.Value1 );

            Expression comparison;
            switch( dateCriterion.Condition )
            {
                case DateCondition.GreaterThan : 
                    comparison = Expression.GreaterThan( projection.Body, constant );
                    break;
                case DateCondition.GreaterThanOrEqualTo:
                    comparison = Expression.GreaterThanOrEqual( projection.Body, constant );
                    break;
                case DateCondition.LessThan:
                    comparison = Expression.LessThan( projection.Body, constant );
                    break;
                case DateCondition.LessThanOrEqualTo:
                    comparison = Expression.LessThanOrEqual( projection.Body, constant );
                    break;

                case DateCondition.Between:
                    {
                        var comparisonLeft =  Expression.GreaterThanOrEqual( projection.Body, Expression.Constant( ( DateTime )dateCriterion.Value1 ) );
                        var comparisonRight = Expression.LessThanOrEqual(    projection.Body, Expression.Constant( ( DateTime )dateCriterion.Value2 ) );

                        comparison = Expression.AndAlso( comparisonLeft, comparisonRight );
                        break;
                    }
                default:
                    return null;//TODO:Something bad happens here.
            }