diff --git a/QueryKit.IntegrationTests/Tests/FilterParameterTests.cs b/QueryKit.IntegrationTests/Tests/FilterParameterTests.cs index e630b88..e4c5105 100644 --- a/QueryKit.IntegrationTests/Tests/FilterParameterTests.cs +++ b/QueryKit.IntegrationTests/Tests/FilterParameterTests.cs @@ -8,8 +8,8 @@ namespace QueryKit.IntegrationTests.Tests; public class FilterParameterTests() : TestBase { - private static readonly QueryKitConfiguration ParameterizedConfig = - new(settings => settings.ParameterizeFilterValues = true); + private static readonly QueryKitConfiguration LiteralConfig = + new(settings => settings.ParameterizeFilterValues = false); [Theory] [InlineData("""Title == "lamb" """, """Title == "chicken" """)] @@ -48,7 +48,7 @@ public async Task in_list_is_one_array_parameter_and_still_filters() await testingServiceScope.InsertAsync(lamb, chicken, beef); var input = $"""Title ^^* ["{lamb.Title!.ToUpper()}", "{chicken.Title}"]"""; - var query = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, ParameterizedConfig); + var query = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input); var people = await query.ToListAsync(); SqlWithoutParameterValues(query).Should().Contain("= ANY (@"); @@ -60,18 +60,18 @@ public async Task in_list_is_one_array_parameter_and_still_filters() [InlineData("Age > 30", "> 30")] [InlineData("Date == 2022-07-01", "DATE '2022-07-01'")] [InlineData("(Age + 5) > 30", "+ 5")] - public void filter_values_are_sql_literals_by_default(string input, string expectedLiteral) + public void filter_values_are_sql_literals_when_parameters_are_off(string input, string expectedLiteral) { var testingServiceScope = new TestingServiceScope(); - var sql = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input).ToQueryString(); + var sql = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, LiteralConfig).ToQueryString(); sql.Should().NotContain("@"); sql.Should().Contain(expectedLiteral); } [Fact] - public async Task in_list_is_a_literal_list_by_default_and_still_filters() + public async Task in_list_is_a_literal_list_when_parameters_are_off_and_still_filters() { var testingServiceScope = new TestingServiceScope(); var lamb = new FakeTestingPersonBuilder().WithTitle($"lamb {Guid.NewGuid()}").Build(); @@ -80,7 +80,7 @@ public async Task in_list_is_a_literal_list_by_default_and_still_filters() await testingServiceScope.InsertAsync(lamb, chicken, beef); var input = $"""Title ^^ ["{lamb.Title}", "{chicken.Title}"]"""; - var query = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input); + var query = testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, LiteralConfig); var people = await query.ToListAsync(); query.ToQueryString().Should().Contain($"IN ('{lamb.Title}', '{chicken.Title}')"); @@ -88,7 +88,7 @@ public async Task in_list_is_a_literal_list_by_default_and_still_filters() } private static string SqlWithoutParameterValues(TestingServiceScope testingServiceScope, string input) - => SqlWithoutParameterValues(testingServiceScope.DbContext().People.ApplyQueryKitFilter(input, ParameterizedConfig)); + => SqlWithoutParameterValues(testingServiceScope.DbContext().People.ApplyQueryKitFilter(input)); // ToQueryString() writes each parameter value in a "-- @p='...'" comment line before the SQL. private static string SqlWithoutParameterValues(IQueryable query) diff --git a/QueryKit.UnitTests/FilterParserTests.cs b/QueryKit.UnitTests/FilterParserTests.cs index a72fadd..420ec16 100644 --- a/QueryKit.UnitTests/FilterParserTests.cs +++ b/QueryKit.UnitTests/FilterParserTests.cs @@ -42,7 +42,7 @@ public void complex_with_lots_of_types() var filterExpression = FilterParser.ParseFilter(input); filterExpression.ToDisplayString().Should() - .Be(""""x => (((((((((x.Title != null) AndAlso x.Title.ToLower().Contains("waffle & chicken".ToLower())) AndAlso (x.Age > 30)) OrElse (x.Id == aa648248-cb69-4217-ac95-d7484795afb2)) OrElse (x.Title == "lamb")) OrElse (x.Title == null)) AndAlso ((x.Age < 18) OrElse ((x.BirthMonth == new Nullable`1(January)) AndAlso ((x.Title != null) AndAlso x.Title.StartsWith("ally"))))) OrElse (x.Rating > 3.5)) OrElse ((x.SpecificDate == new Nullable`1(new DateTimeOffset(637922304030000000, 00:00:00))) AndAlso ((x.Date == new Nullable`1(new DateOnly(2022, 7, 1))) OrElse (x.Time == new Nullable`1(new TimeOnly(0, 0, 3, 0, 0))))))""""); + .Be(""""x => (((((((((x.Title != null) AndAlso x.Title.ToLower().Contains("waffle & chicken".ToLower())) AndAlso (x.Age > 30)) OrElse (x.Id == aa648248-cb69-4217-ac95-d7484795afb2)) OrElse (x.Title == "lamb")) OrElse (x.Title == null)) AndAlso ((x.Age < 18) OrElse ((x.BirthMonth == January) AndAlso ((x.Title != null) AndAlso x.Title.StartsWith("ally"))))) OrElse (x.Rating > 3.5)) OrElse ((x.SpecificDate == new Nullable`1(new DateTimeOffset(637922304030000000, 00:00:00))) AndAlso ((x.Date == new Nullable`1(new DateOnly(2022, 7, 1))) OrElse (x.Time == new Nullable`1(new TimeOnly(0, 0, 3, 0, 0))))))""""); } [Fact] diff --git a/QueryKit.UnitTests/FilterValueParameterTests.cs b/QueryKit.UnitTests/FilterValueParameterTests.cs index 6f0e0a4..b111f03 100644 --- a/QueryKit.UnitTests/FilterValueParameterTests.cs +++ b/QueryKit.UnitTests/FilterValueParameterTests.cs @@ -7,8 +7,8 @@ namespace QueryKit.UnitTests; public class FilterValueParameterTests { - private static readonly QueryKitConfiguration ParameterizedConfig = - new(settings => settings.ParameterizeFilterValues = true); + private static readonly QueryKitConfiguration LiteralConfig = + new(settings => settings.ParameterizeFilterValues = false); [Theory] [InlineData("""Title == "lamb" """)] @@ -31,7 +31,7 @@ public class FilterValueParameterTests [InlineData("(Age + 5) > 30")] public void filter_values_are_field_reads_so_ef_core_sends_them_as_parameters(string input) { - var filterExpression = FilterParser.ParseFilter(input, ParameterizedConfig); + var filterExpression = FilterParser.ParseFilter(input); var constants = new ConstantCollector(); constants.Visit(filterExpression); @@ -50,9 +50,9 @@ public void filter_values_are_field_reads_so_ef_core_sends_them_as_parameters(st [InlineData("Date == 2022-07-01", "x => (x.Date == new Nullable`1(new DateOnly(2022, 7, 1)))")] [InlineData("""Time == "00:00:03.123456" """, "x => (x.Time == new Nullable`1(new TimeOnly(0, 0, 3, 123, 456)))")] [InlineData("(Age + 5) > 30", "x => ((x.Age + Convert(5, Nullable`1)) > Convert(30, Nullable`1))")] - public void filter_values_are_constants_by_default(string input, string expected) + public void filter_values_are_constants_when_parameters_are_off(string input, string expected) { - var filterExpression = FilterParser.ParseFilter(input); + var filterExpression = FilterParser.ParseFilter(input, LiteralConfig); filterExpression.ToString().Should().Be(expected); } @@ -64,9 +64,9 @@ public void filter_values_are_constants_by_default(string input, string expected [InlineData("""Title ^^* ["lamb", "chicken"]""")] [InlineData("Age ^^ [18, 30]")] [InlineData("(Age + 5) > 30")] - public void filter_values_do_not_use_the_holder_by_default(string input) + public void filter_values_do_not_use_the_holder_when_parameters_are_off(string input) { - var filterExpression = FilterParser.ParseFilter(input); + var filterExpression = FilterParser.ParseFilter(input, LiteralConfig); var constants = new ConstantCollector(); constants.Visit(filterExpression); @@ -79,7 +79,7 @@ public void filter_values_do_not_use_the_holder_by_default(string input) [Fact] public void filter_values_keep_their_value_and_type() { - var filterExpression = FilterParser.ParseFilter("""Time == "00:00:03.123456" """, ParameterizedConfig); + var filterExpression = FilterParser.ParseFilter("""Time == "00:00:03.123456" """); var comparison = (BinaryExpression)filterExpression.Body; var read = (MemberExpression)comparison.Right; diff --git a/QueryKit/Configuration/QueryKitSettings.cs b/QueryKit/Configuration/QueryKitSettings.cs index e79ba3c..a2d27a2 100644 --- a/QueryKit/Configuration/QueryKitSettings.cs +++ b/QueryKit/Configuration/QueryKitSettings.cs @@ -44,10 +44,10 @@ public class QueryKitSettings public CaseInsensitiveMode CaseInsensitiveComparison { get; set; } = CaseInsensitiveMode.Lower; /// - /// When true, filter values are field reads that EF Core sends as SQL parameters. When false (the default), - /// filter values are constants that EF Core writes into the SQL as literals. + /// When true (the default), filter values are field reads that EF Core sends as SQL parameters. When false, + /// filter values are constants that EF Core writes into the SQL as literals, the same as v1.14.2. /// - public bool ParameterizeFilterValues { get; set; } + public bool ParameterizeFilterValues { get; set; } = true; /// /// What the filter parser does with a clause on a prevented or unknown property. The default is diff --git a/QueryKit/FilterParser.cs b/QueryKit/FilterParser.cs index 04eb070..bfa4b46 100644 --- a/QueryKit/FilterParser.cs +++ b/QueryKit/FilterParser.cs @@ -26,7 +26,7 @@ public static Expression> ParseFilter(string input, IQueryKitCo var parameter = Expression.Parameter(typeof(T), "x"); Expression expr; var parameterizeBefore = FilterValue.Parameterize; - FilterValue.Parameterize = config is QueryKitConfiguration { ParameterizeFilterValues: true }; + FilterValue.Parameterize = (config as QueryKitConfiguration)?.ParameterizeFilterValues ?? true; try { expr = ExprParser(parameter, config).End().Parse(input);