代码之家  ›  专栏  ›  技术社区  ›  Aaron Fischer

如何从lambda表达式中提取成员路径

  •  1
  • Aaron Fischer  · 技术社区  · 14 年前

    我有一个方法可以将日期条件添加到我的LINQ查询中。我要做的是传递x。作为一个参数到期,使它能够与任何日期一起工作。有什么想法吗?

    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 回复  |  直到 14 年前
        1
  •  1
  •   Jon Skeet    14 年前

    必须将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 剩下的应该是 相当地 容易的。。。

        2
  •  0
  •   Aaron Fischer    14 年前

    这就是我的结局。 我可以将此方法称为.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.
                }