Uploaded image for project: 're-motion'
  1. re-motion
  2. RM-3656

Provide an automatic transformation for InvocationExpressions applied to LambdaExpressions

    Details

      Description

      Support for query combinations involving the invocation of LambdaExpressions similar to the following:

      Cooks.Where (c => ((Func<Cook, bool>) (c1 => c1.Name != null)) (c))
      

      In this case, a LambdaExpression is constructed and immediately invoked in the Where condition. This can be detected and inlined in order to produce an expression equivalent to the Where condition in the following query:

      Cooks.Where (c => c.Name != null)
      

      (In this example, the C# compiler adds a trivial Convert expression that converts the constructed lambda to its own type. The transformation should be able to handle this.)

      This is useful for specification libraries that need to combine predicates that are given in the form of LambdaExpressions, as in the following example:

      Expression<Func<Order, bool>> predicate1 = o => o.OrderNumber > 100;
      Expression<Func<Order, bool>> predicate2 = o => o.OrderDate > new DateTime (2010, 01, 01);
      var combinedPredicate = 
          Expression.Lambda<Func<Order, bool>> (
              Expression.AndAlso (
                  predicate1.Body,
                  Expression.Invoke (predicate2, predicate1.Parameters.Cast<Expression>()),
              ),
              predicate1.Parameters);
      var query = Orders.Where (combinedPredicate);
      

      The simplification described above is added via a transformation implemented in the InvocationOfLambdaExpressionTransformer class. The transformation, which is enabled by default, replaces expressions invoking a LambdaExpression with a simplified, inlined version of the LambdaExpression's body. (It cannot inline invocations of delegate constants.)

      For LINQ providers customizing the expression tree preprocessing steps applied by the re-linq front-end, add an instance of the InvocationOfLambdaExpressionTransformer class to the ExpressionTransformationStep.

        Attachments

        There are no Sub-Tasks for this issue.

          Activity

          Hide
          fabian.schmied Fabian Schmied added a comment -

          Workaround until this is implemented:

          Expression<Func<Order, bool>> predicate1 = o => o.OrderNumber > 100;
          Expression<Func<Order, bool>> predicate2 = o => o.OrderDate > new DateTime (2010, 01, 01);
          var combinedPredicate = 
              Expression.Lambda<Func<Order, bool>> (
                  Expression.AndAlso (
                      predicate1.Body,
                      ReplacingExpressionTreeVisitor.Replace (predicate2.Parameters.Single(), predicate1.Parameters.Single(), predicate2.Body)
                  ),
                  predicate1.Parameters);
          var query = Orders.Where (combinedPredicate);
          
          Show
          fabian.schmied Fabian Schmied added a comment - Workaround until this is implemented: Expression<Func<Order, bool>> predicate1 = o => o.OrderNumber > 100; Expression<Func<Order, bool>> predicate2 = o => o.OrderDate > new DateTime (2010, 01, 01); var combinedPredicate = Expression.Lambda<Func<Order, bool>> ( Expression.AndAlso ( predicate1.Body, ReplacingExpressionTreeVisitor.Replace (predicate2.Parameters.Single(), predicate1.Parameters.Single(), predicate2.Body) ), predicate1.Parameters); var query = Orders.Where (combinedPredicate);

            People

            • Assignee:
              fabian.schmied Fabian Schmied
              Reporter:
              fabian.schmied Fabian Schmied
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 2 hours
                2h