diff --git a/src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs b/src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs index 1c72f66c..0c35de6a 100644 --- a/src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs +++ b/src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs @@ -675,7 +675,7 @@ public static dynamic FirstOrDefault([NotNull] this IQueryable source, [NotNull] /// [PublicAPI] public static IQueryable GroupBy([NotNull] this IQueryable source, [NotNull] ParsingConfig config, [NotNull] string keySelector, [NotNull] string resultSelector, object[] args) - { + { return InternalGroupBy(source, config, keySelector, resultSelector, null, args); } @@ -695,7 +695,7 @@ public static IQueryable GroupBy([NotNull] this IQueryable source, [NotNull] Par return InternalGroupBy(source, config, keySelector, resultSelector, equalityComparer, args); } - internal static IQueryable InternalGroupBy([NotNull] IQueryable source, [NotNull] ParsingConfig config, [NotNull] string keySelector, [NotNull] string resultSelector, IEqualityComparer equalityComparer, object[] args) + internal static IQueryable InternalGroupBy([NotNull] IQueryable source, [NotNull] ParsingConfig config, [NotNull] string keySelector, [NotNull] string resultSelector, IEqualityComparer equalityComparer, object[] args) { Check.NotNull(source, nameof(source)); Check.NotNull(config, nameof(config)); @@ -705,7 +705,7 @@ internal static IQueryable InternalGroupBy([NotNull] IQueryable source, [NotNul bool createParameterCtor = config?.EvaluateGroupByAtDatabase ?? SupportsLinqToObjects(config, source); LambdaExpression keyLambda = DynamicExpressionParser.ParseLambda(config, createParameterCtor, source.ElementType, null, keySelector, args); LambdaExpression elementLambda = DynamicExpressionParser.ParseLambda(config, createParameterCtor, source.ElementType, null, resultSelector, args); - + Expression optimized = null; if (equalityComparer == null) { @@ -720,9 +720,9 @@ internal static IQueryable InternalGroupBy([NotNull] IQueryable source, [NotNul optimized = OptimizeExpression(Expression.Call( typeof(Queryable), nameof(Queryable.GroupBy), new[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type }, - source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda), + source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda), Expression.Constant(equalityComparer, equalityComparerGenericType))); - } + } return source.Provider.CreateQuery(optimized); } @@ -804,7 +804,7 @@ public static IQueryable GroupBy([NotNull] this IQueryable source, [NotNull] str /// [PublicAPI] public static IQueryable GroupBy([NotNull] this IQueryable source, [NotNull] ParsingConfig config, [NotNull] string keySelector, [CanBeNull] params object[] args) - { + { return InternalGroupBy(source, config, keySelector, null, args); } @@ -1598,7 +1598,7 @@ internal static IOrderedQueryable InternalOrderBy([NotNull] IQueryable source, [ foreach (DynamicOrdering dynamicOrdering in dynamicOrderings) { if (comparer == null) - { + { queryExpr = Expression.Call( typeof(Queryable), dynamicOrdering.MethodName, new[] { source.ElementType, dynamicOrdering.Selector.Type }, @@ -1606,11 +1606,11 @@ internal static IOrderedQueryable InternalOrderBy([NotNull] IQueryable source, [ } else { - var comparerGenericType = typeof(IComparer<>).MakeGenericType(dynamicOrdering.Selector.Type); + var comparerGenericType = typeof(IComparer<>).MakeGenericType(dynamicOrdering.Selector.Type); queryExpr = Expression.Call( typeof(Queryable), dynamicOrdering.MethodName, new[] { source.ElementType, dynamicOrdering.Selector.Type }, - queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)), + queryExpr, Expression.Quote(Expression.Lambda(dynamicOrdering.Selector, parameters)), Expression.Constant(comparer, comparerGenericType)); } } @@ -2504,7 +2504,7 @@ public static IOrderedQueryable ThenBy([NotNull] this IOrdered { return (IOrderedQueryable)InternalThenBy((IOrderedQueryable)source, config, ordering, comparer, args); } - + /// /// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key. /// @@ -2569,7 +2569,7 @@ internal static IOrderedQueryable InternalThenBy([NotNull] IOrderedQueryable sou foreach (DynamicOrdering dynamicOrdering in dynamicOrderings) { if (comparer == null) - { + { queryExpr = Expression.Call( typeof(Queryable), dynamicOrdering.MethodName, new[] { source.ElementType, dynamicOrdering.Selector.Type }, @@ -2684,6 +2684,12 @@ public static IQueryable Where([NotNull] this IQueryable source, [NotNull] Lambd var optimized = OptimizeExpression(Expression.Call(typeof(Queryable), nameof(Queryable.Where), new[] { source.ElementType }, source.Expression, Expression.Quote(lambda))); return source.Provider.CreateQuery(optimized); } + + /// + public static IQueryable Where([NotNull] this IQueryable source, [NotNull] LambdaExpression lambda) + { + return (IQueryable)Where((IQueryable)source, lambda); + } #endregion #region Private Helpers diff --git a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Where.cs b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Where.cs index a37abeea..7c20e786 100644 --- a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Where.cs +++ b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Where.cs @@ -3,6 +3,8 @@ using System.Linq.Dynamic.Core.Tests.Helpers; using System.Linq.Dynamic.Core.Tests.Helpers.Entities; using System.Linq.Dynamic.Core.Tests.Helpers.Models; +using System.Linq.Expressions; +using FluentAssertions; using Xunit; namespace System.Linq.Dynamic.Core.Tests @@ -103,6 +105,38 @@ public void Where_Dynamic_DateTime_Equals_Null() Assert.Equal(expected, result2); } + [Fact] + public void Where_Dynamic_IQueryable_LambdaExpression() + { + // Arrange + var queryable = (IQueryable)new[] { new User { Income = 5 } }.AsQueryable(); + + Expression> userExpression = u => u.Income > 1; + LambdaExpression lambdaExpression = userExpression; + + // Act + var result = queryable.Where(lambdaExpression); + + // Assert + result.Should().HaveCount(1); + } + + [Fact] + public void Where_Dynamic_IQueryableT_LambdaExpression() + { + // Arrange + var queryable = new[] { new User { Income = 5 } }.AsQueryable(); + + Expression> userExpression = u => u.Income > 1; + LambdaExpression lambdaExpression = userExpression; + + // Act + var result = queryable.Where(lambdaExpression); + + // Assert + result.Should().HaveCount(1); + } + [Fact] public void Where_Dynamic_Exceptions() { @@ -116,7 +150,7 @@ public void Where_Dynamic_Exceptions() Assert.Throws(() => qry.Where("Id=123")); Assert.Throws(() => DynamicQueryableExtensions.Where(null, "Id=1")); - Assert.Throws(() => qry.Where(null)); + Assert.Throws(() => qry.Where((string)null)); Assert.Throws(() => qry.Where("")); Assert.Throws(() => qry.Where(" ")); }