From f2a55392a1a04a745b364a8edb989086bd579989 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Mon, 13 May 2024 11:14:05 +0200 Subject: [PATCH] EF Core 8 provider (and refactoring around). --- build.ps1 | 27 +- include.ps1 | 4 - src/Directory.Build.props | 3 +- .../EntityFramework.Firebird.Tests.csproj | 1 - .../EntityFramework.Firebird.csproj | 8 +- .../FirebirdSql.Data.FirebirdClient.csproj | 1 + ...meworkCore.Firebird.FunctionalTests.csproj | 3 +- .../Helpers/ModelHelpers.cs | 28 +- .../MigrationsFbTest.cs | 36 +- ...nsCollectionsSplitSharedTypeQueryFbTest.cs | 7 + .../Query/ComplexTypeQueryFbTest.cs | 198 +++++++ .../Query/FromSqlQueryFbTest.cs | 11 +- .../Query/FunkyDataQueryFbTest.cs | 8 + .../Query/GearsOfWarQueryFbTest.cs | 28 + ...ompleteMappingInheritanceQueryFbFixture.cs | 4 +- ...IncompleteMappingInheritanceQueryFbTest.cs | 8 +- .../InheritanceRelationshipsQueryFbTest.cs | 17 +- ...onSharedPrimitiveCollectionsQueryFbTest.cs | 191 +++++++ .../NorthwindAggregateOperatorsQueryFbTest.cs | 26 + .../NorthwindChangeTrackingQueryFbTest.cs | 3 +- .../Query/NorthwindCompiledQueryFbTest.cs | 63 +-- .../Query/NorthwindFunctionsQueryFbTest.cs | 42 +- .../Query/NorthwindJoinQueryFbTest.cs | 7 + .../NorthwindMiscellaneousQueryFbTest.cs | 14 + .../Query/NorthwindQueryFbFixture.cs | 1 + ...ixture.cs => OperatorsProceduralFbTest.cs} | 11 +- .../Query/OperatorsQueryFbTest.cs | 62 +++ .../Query/OptionalDependentQueryFbFixture.cs | 27 + .../Query/OptionalDependentQueryFbTest.cs | 100 ++++ .../Query/PrimitiveCollectionsQueryFbTest.cs | 481 ++++++++++++++++++ .../Query/QueryFilterFuncletizationFbTest.cs | 26 +- .../Query/SqlExecutorFbTest.cs | 43 +- .../Query/SqlQueryFbTest.cs | 148 ++++++ .../TPCFiltersInheritanceQueryFbFixture.cs | 2 +- .../Query/TPCGearsOfWarQueryFbTest.cs | 47 +- .../Query/TPCInheritanceQueryFbFixture.cs | 2 +- .../Query/TPCInheritanceQueryFbTest.cs | 6 +- .../Query/TPCInheritanceQueryFbTestBase.cs | 6 +- .../Query/TPCInheritanceQueryHiLoFbTest.cs | 6 +- ...=> TPHFiltersInheritanceQueryFbFixture.cs} | 4 +- ...cs => TPHFiltersInheritanceQueryFbTest.cs} | 4 +- ...ure.cs => TPHInheritanceQueryFbFixture.cs} | 2 +- ...FbTest.cs => TPHInheritanceQueryFbTest.cs} | 7 +- .../TPTFiltersInheritanceQueryFbFixture.cs | 2 +- .../Query/TPTGearsOfWarQueryFbTest.cs | 68 ++- .../Query/TPTInheritanceQueryFbTest.cs | 5 +- .../Query/UdfDbFunctionFbTests.cs | 53 +- ....EntityFrameworkCore.Firebird.Tests.csproj | 1 - .../Migrations/MigrationsTests.cs | 15 +- .../Extensions/FbPropertyExtensions.cs | 20 +- .../FbServiceCollectionExtensions.cs | 1 + ...irdSql.EntityFrameworkCore.Firebird.csproj | 10 +- .../Migrations/FbMigrationsSqlGenerator.cs | 8 +- .../Internal/FbDateOnlyMethodTranslator.cs | 66 +++ .../Internal/FbStringContainsTranslator.cs | 5 +- .../Internal/FbStringEndsWithTranslator.cs | 9 +- .../Internal/FbStringStartsWithTranslator.cs | 9 +- .../Query/Internal/FbQueryRootProcessor.cs | 33 ++ .../Query/Internal/FbQuerySqlGenerator.cs | 74 ++- .../FbQueryTranslationPreprocessor.cs | 34 ++ .../FbQueryTranslationPreprocessorFactory.cs | 37 ++ .../Storage/Internal/FbTypeMappingSource.cs | 2 +- .../Internal/FbValueGeneratorCache.cs | 2 +- .../Internal/FbValueGeneratorSelector.cs | 6 +- src/NETProvider.sln | 3 +- src/Versions.props | 18 + tests.ps1 | 7 +- 67 files changed, 1933 insertions(+), 278 deletions(-) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexTypeQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{InheritanceRelationshipsQueryFbFixture.cs => OperatorsProceduralFbTest.cs} (68%) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbFixture.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{FiltersInheritanceQueryFbFixture.cs => TPHFiltersInheritanceQueryFbFixture.cs} (85%) rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{FiltersInheritanceQueryFbTest.cs => TPHFiltersInheritanceQueryFbTest.cs} (79%) rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{InheritanceQueryFbFixture.cs => TPHInheritanceQueryFbFixture.cs} (94%) rename src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/{InheritanceQueryFbTest.cs => TPHInheritanceQueryFbTest.cs} (74%) create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryRootProcessor.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessor.cs create mode 100644 src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessorFactory.cs create mode 100644 src/Versions.props diff --git a/build.ps1 b/build.ps1 index c5b84ce41..9a321609d 100644 --- a/build.ps1 +++ b/build.ps1 @@ -8,7 +8,9 @@ $baseDir = Split-Path -Parent $PSCommandPath . "$baseDir\include.ps1" $outDir = "$baseDir\out" -$version = '' +$versionProvider = '' +$versionEFCore = '' +$versionEF6 = '' function Clean() { if (Test-Path $outDir) { @@ -29,19 +31,28 @@ function Build() { b 'Restore' $False b 'Restore' b 'Build' - $script:version = (Get-Item $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\$(Get-UsedTargetFramework)\FirebirdSql.Data.FirebirdClient.dll).VersionInfo.ProductVersion -replace '(\d+)\.(\d+)\.(\d+)(-[a-z0-9]+)?(.*)','$1.$2.$3$4' +} + +function Versions() { + function v($file) { + return (Get-Item $file).VersionInfo.ProductVersion -replace '(\d+)\.(\d+)\.(\d+)(-[a-z0-9]+)?.*','$1.$2.$3$4' + } + $script:versionProvider = v $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\net8.0\FirebirdSql.Data.FirebirdClient.dll + $script:versionEFCore = v $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\net8.0\FirebirdSql.EntityFrameworkCore.Firebird.dll + $script:versionEF6 = v $baseDir\src\EntityFramework.Firebird\bin\$Configuration\net48\EntityFramework.Firebird.dll } function NuGets() { - cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$version.nupkg $outDir - cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$version.nupkg $outDir - cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$version.nupkg $outDir + cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$versionProvider.nupkg $outDir + cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$versionEFCore.nupkg $outDir + cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$versionEF6.nupkg $outDir - cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$version.snupkg $outDir - cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$version.snupkg $outDir - cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$version.snupkg $outDir + cp $baseDir\src\FirebirdSql.Data.FirebirdClient\bin\$Configuration\FirebirdSql.Data.FirebirdClient.$versionProvider.snupkg $outDir + cp $baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird\bin\$Configuration\FirebirdSql.EntityFrameworkCore.Firebird.$versionEFCore.snupkg $outDir + cp $baseDir\src\EntityFramework.Firebird\bin\$Configuration\EntityFramework.Firebird.$versionEF6.snupkg $outDir } Clean Build +Versions NuGets diff --git a/include.ps1 b/include.ps1 index cb57d88dd..a713a7a9f 100644 --- a/include.ps1 +++ b/include.ps1 @@ -4,8 +4,4 @@ function Check-ExitCode() { echo "Non-zero ($exitCode) exit code. Exiting..." exit $exitCode } -} - -function Get-UsedTargetFramework() { - return 'net8.0' } \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a1348f8bb..e01e0d79d 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,11 +1,10 @@ + latest portable - 10.0.0 - FirebirdSQL NETProvider FirebirdSQL diff --git a/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj b/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj index bd91e8ab5..52ce20027 100644 --- a/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj +++ b/src/EntityFramework.Firebird.Tests/EntityFramework.Firebird.Tests.csproj @@ -22,7 +22,6 @@ - diff --git a/src/EntityFramework.Firebird/EntityFramework.Firebird.csproj b/src/EntityFramework.Firebird/EntityFramework.Firebird.csproj index 4e7a0f275..8457ebd6e 100644 --- a/src/EntityFramework.Firebird/EntityFramework.Firebird.csproj +++ b/src/EntityFramework.Firebird/EntityFramework.Firebird.csproj @@ -9,6 +9,7 @@ true + $(EF6ProviderVersion) NETProvider - Entity Framework Provider (c) 2014-$(CopyrightEndYear) @@ -45,7 +46,7 @@ - + @@ -53,7 +54,10 @@ - + + + + diff --git a/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient.csproj b/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient.csproj index ac5377a3d..25dcfcbb1 100644 --- a/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient.csproj +++ b/src/FirebirdSql.Data.FirebirdClient/FirebirdSql.Data.FirebirdClient.csproj @@ -10,6 +10,7 @@ true + $(ProviderVersion) NETProvider - ADO.NET Data Provider (c) 2002-$(CopyrightEndYear) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj index e02397c02..bbadea15a 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj @@ -11,7 +11,7 @@ true - + @@ -20,7 +20,6 @@ - diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Helpers/ModelHelpers.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Helpers/ModelHelpers.cs index f2d9b2371..96fc88b6b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Helpers/ModelHelpers.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Helpers/ModelHelpers.cs @@ -30,12 +30,30 @@ public static void SetStringLengths(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { - foreach (var property in entityType.GetProperties()) + HandleProperties(entityType.GetProperties()); + HandleComplexProperties(entityType.GetComplexProperties()); + } + + void HandleProperties(IEnumerable properties) + { + foreach (var property in properties) + { + SetStringLength(property); + } + } + void HandleComplexProperties(IEnumerable complexProperties) + { + foreach (var cp in complexProperties) + { + HandleProperties(cp.ComplexType.GetProperties()); + HandleComplexProperties(cp.ComplexType.GetComplexProperties()); + } + } + void SetStringLength(IMutableProperty property) + { + if (property.ClrType == typeof(string) && property.GetMaxLength() == null) { - if (property.ClrType == typeof(string) && property.GetMaxLength() == null) - { - property.SetMaxLength(500); - } + property.SetMaxLength(500); } } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs index d27631822..dc0c08b49 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/MigrationsFbTest.cs @@ -129,8 +129,10 @@ public MigrationsFbTest(MigrationsFbFixture fixture) [Fact(Skip = SkipReason)] public override Task Add_column_with_collation() => base.Add_column_with_collation(); - [Fact(Skip = SkipReason)] - public override Task Add_column_computed_with_collation() => base.Add_column_computed_with_collation(); + [Theory(Skip = SkipReason)] + [InlineData(true)] + [InlineData(false)] + public override Task Add_column_computed_with_collation(bool stored) => base.Add_column_computed_with_collation(stored); [Fact(Skip = SkipReason)] public override Task Add_column_shared() => base.Add_column_shared(); @@ -324,6 +326,36 @@ public MigrationsFbTest(MigrationsFbFixture fixture) [Fact(Skip = SkipReason)] public override Task Drop_primary_key_string() => base.Drop_primary_key_string(); + [Fact(Skip = SkipReason)] + public override Task Alter_sequence_restart_with() => base.Alter_sequence_restart_with(); + + [Fact(Skip = SkipReason)] + public override Task Add_column_with_unbounded_max_length() => base.Add_column_with_unbounded_max_length(); + + [Fact(Skip = SkipReason)] + public override Task Add_optional_primitive_collection_to_existing_table() => base.Add_optional_primitive_collection_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitve_collection_to_existing_table() => base.Add_required_primitve_collection_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitve_collection_with_custom_converter_and_custom_default_value_to_existing_table() => base.Add_required_primitve_collection_with_custom_converter_and_custom_default_value_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitve_collection_with_custom_default_value_to_existing_table() => base.Add_required_primitve_collection_with_custom_default_value_to_existing_table(); + + [Fact(Skip = SkipReason)] + public override Task Create_table_with_complex_type_with_required_properties_on_derived_entity_in_TPH() => base.Create_table_with_complex_type_with_required_properties_on_derived_entity_in_TPH(); + + [Fact(Skip = SkipReason)] + public override Task Create_table_with_optional_primitive_collection() => base.Create_table_with_optional_primitive_collection(); + + [Fact(Skip = SkipReason)] + public override Task Create_table_with_required_primitive_collection() => base.Create_table_with_required_primitive_collection(); + + [Fact(Skip = SkipReason)] + public override Task Add_required_primitve_collection_with_custom_default_value_sql_to_existing_table() => Task.CompletedTask; + public class MigrationsFbFixture : MigrationsFixtureBase { protected override string StoreName => nameof(MigrationsFbTest); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryFbTest.cs index e5641d09e..0f470b08b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryFbTest.cs @@ -146,4 +146,11 @@ public override Task Take_Select_collection_Take(bool async) { return base.Take_Select_collection_Take(async); } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filtered_include_Skip_Take_with_another_Skip_Take_on_top_level(bool async) + { + return base.Filtered_include_Skip_Take_with_another_Skip_Take_on_top_level(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexTypeQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexTypeQueryFbTest.cs new file mode 100644 index 000000000..0e84b62ab --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/ComplexTypeQueryFbTest.cs @@ -0,0 +1,198 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System; +using System.Linq; +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestModels.ComplexTypeModel; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class ComplexTypeQueryFbTest : ComplexTypeQueryRelationalTestBase +{ + public ComplexTypeQueryFbTest(ComplexTypeQueryFbFixture fixture) + : base(fixture) + { } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_complex_type_via_optional_navigation(bool async) + { + return Assert.ThrowsAsync(() => base.Project_complex_type_via_optional_navigation(async)); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_struct_complex_type_via_optional_navigation(bool async) + { + return Assert.ThrowsAsync(() => base.Project_struct_complex_type_via_optional_navigation(async)); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Union_property_in_complex_type(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Select(c => c.ShippingAddress.AddressLine1) + .Union(ss.Set().Select(c => c.BillingAddress.AddressLine1))); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_entity_with_nested_complex_type_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_entity_with_nested_complex_type_twice_with_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_entity_with_nested_complex_type_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_entity_with_nested_complex_type_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_entity_with_struct_nested_complex_type_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_entity_with_struct_nested_complex_type_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_entity_with_struct_nested_complex_type_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_entity_with_struct_nested_complex_type_twice_with_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_nested_complex_type_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_nested_complex_type_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_nested_complex_type_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_nested_complex_type_twice_with_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_struct_nested_complex_type_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_struct_nested_complex_type_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_same_struct_nested_complex_type_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Project_same_struct_nested_complex_type_twice_with_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Union_of_same_entity_with_nested_complex_type_projected_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Union_of_same_entity_with_nested_complex_type_projected_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Union_of_same_entity_with_nested_complex_type_projected_twice_with_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Union_of_same_nested_complex_type_projected_twice_with_double_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Union_of_same_nested_complex_type_projected_twice_with_double_pushdown(async); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task Union_of_same_nested_complex_type_projected_twice_with_pushdown(bool async) + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return Task.CompletedTask; + return base.Union_of_same_nested_complex_type_projected_twice_with_pushdown(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Same_entity_with_complex_type_projected_twice_with_pushdown_as_part_of_another_projection(bool async) + { + return base.Same_entity_with_complex_type_projected_twice_with_pushdown_as_part_of_another_projection(async); + } + + public class ComplexTypeQueryFbFixture : ComplexTypeQueryRelationalFixtureBase + { + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + ModelHelpers.SetStringLengths(modelBuilder); + } + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs index f306be02a..3c1770985 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FromSqlQueryFbTest.cs @@ -22,7 +22,6 @@ using FirebirdSql.Data.FirebirdClient; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -36,13 +35,6 @@ public FromSqlQueryFbTest(NorthwindQueryFbFixture fixture) : base(fixture) { } - protected override DbParameter CreateDbParameter(string name, object value) - => new FbParameter - { - ParameterName = name, - Value = value - }; - [Theory] [MemberData(nameof(IsAsyncData))] public override async Task FromSql_Count_used_twice_without_parameters(bool async) @@ -164,4 +156,7 @@ public override Task Multiple_occurrences_of_FromSql_with_db_parameter_adds_para { return base.Multiple_occurrences_of_FromSql_with_db_parameter_adds_parameter_only_once(async); } + + protected override DbParameter CreateDbParameter(string name, object value) + => new FbParameter { ParameterName = name, Value = value }; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs index 8510b7af3..da2911974 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FunkyDataQueryFbTest.cs @@ -16,6 +16,7 @@ //$Authors = Jiri Cincura (jiri@cincura.net) using System.Linq; +using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; using Microsoft.EntityFrameworkCore; @@ -31,6 +32,13 @@ public FunkyDataQueryFbTest(FunkyDataQueryFbFixture fixture) : base(fixture) { } + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task String_contains_on_argument_with_wildcard_column(bool async) + { + return base.String_contains_on_argument_with_wildcard_column(async); + } + public class FunkyDataQueryFbFixture : FunkyDataQueryFixtureBase { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs index 3d832cce1..3ae01245b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/GearsOfWarQueryFbTest.cs @@ -390,6 +390,27 @@ public override Task Correlated_collection_with_groupby_with_complex_grouping_ke return base.Correlated_collection_with_groupby_with_complex_grouping_key_not_projecting_identifier_column_with_group_aggregate_in_final_projection(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Subquery_inside_Take_argument(bool async) + { + return base.Subquery_inside_Take_argument(async); + } + + [NotSupportedByProviderTheory] + [MemberData(nameof(IsAsyncData))] + public override Task DateTimeOffset_to_unix_time_milliseconds(bool async) + { + return base.DateTimeOffset_to_unix_time_milliseconds(async); + } + + [NotSupportedByProviderTheory] + [MemberData(nameof(IsAsyncData))] + public override Task DateTimeOffset_to_unix_time_seconds(bool async) + { + return base.DateTimeOffset_to_unix_time_seconds(async); + } + [Theory(Skip = "NETProvider#1008")] [MemberData(nameof(IsAsyncData))] public override Task Where_TimeOnly_IsBetween(bool async) @@ -403,4 +424,11 @@ public override Task Where_TimeOnly_Add_TimeSpan(bool async) { return base.Where_TimeOnly_Add_TimeSpan(async); } + + [Theory(Skip = "Different implicit ordering on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task String_concat_with_null_conditional_argument(bool async) + { + return base.String_concat_with_null_conditional_argument(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbFixture.cs index ac1102d7f..e7187d908 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbFixture.cs @@ -21,7 +21,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class IncompleteMappingInheritanceQueryFbFixture : InheritanceQueryFbFixture +public class IncompleteMappingInheritanceQueryFbFixture : TPHInheritanceQueryFbFixture { - protected override bool IsDiscriminatorMappingComplete => false; + public override bool IsDiscriminatorMappingComplete => false; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbTest.cs index 7be95ad4c..b3730b89a 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/IncompleteMappingInheritanceQueryFbTest.cs @@ -15,14 +15,14 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; +using Xunit.Abstractions; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class IncompleteMappingInheritanceQueryFbTest : InheritanceRelationalQueryTestBase +public class IncompleteMappingInheritanceQueryFbTest : TPHInheritanceQueryTestBase { - public IncompleteMappingInheritanceQueryFbTest(IncompleteMappingInheritanceQueryFbFixture fixture) - : base(fixture) + public IncompleteMappingInheritanceQueryFbTest(IncompleteMappingInheritanceQueryFbFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbTest.cs index 20854abe0..e2fe8d34a 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbTest.cs @@ -17,12 +17,15 @@ using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class InheritanceRelationshipsQueryFbTest : InheritanceRelationshipsQueryTestBase +public class InheritanceRelationshipsQueryFbTest : InheritanceRelationshipsQueryTestBase { public InheritanceRelationshipsQueryFbTest(InheritanceRelationshipsQueryFbFixture fixture) : base(fixture) @@ -361,4 +364,16 @@ public override Task Include_on_derived_type_with_queryable_Cast(bool async) { return base.Include_on_derived_type_with_queryable_Cast(async); } + + public class InheritanceRelationshipsQueryFbFixture : InheritanceRelationshipsQueryRelationalFixture + { + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + ModelHelpers.SetPrimaryKeyGeneration(modelBuilder); + ModelHelpers.SimpleTableNames(modelBuilder); + } + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs new file mode 100644 index 000000000..42e0b1e56 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryFbTest.cs @@ -0,0 +1,191 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class NonSharedPrimitiveCollectionsQueryFbTest : NonSharedPrimitiveCollectionsQueryRelationalTestBase +{ + [NotSupportedOnFirebirdFact] + public override Task Array_of_string() + { + return base.Array_of_string(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_int() + { + return base.Array_of_int(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_long() + { + return base.Array_of_long(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_short() + { + return base.Array_of_short(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_byte() + { + return base.Array_of_byte(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_double() + { + return base.Array_of_double(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_float() + { + return base.Array_of_float(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_decimal() + { + return base.Array_of_decimal(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_DateTime() + { + return base.Array_of_DateTime(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_DateTime_with_milliseconds() + { + return base.Array_of_DateTime_with_milliseconds(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_DateTime_with_microseconds() + { + return base.Array_of_DateTime_with_microseconds(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_DateOnly() + { + return base.Array_of_DateOnly(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_TimeOnly() + { + return base.Array_of_TimeOnly(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_TimeOnly_with_milliseconds() + { + return base.Array_of_TimeOnly_with_milliseconds(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_TimeOnly_with_microseconds() + { + return base.Array_of_TimeOnly_with_microseconds(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_DateTimeOffset() + { + return base.Array_of_DateTimeOffset(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_bool() + { + return base.Array_of_bool(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_Guid() + { + return base.Array_of_Guid(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_byte_array() + { + return base.Array_of_byte_array(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_enum() + { + return base.Array_of_enum(); + } + + [NotSupportedOnFirebirdFact] + public override Task Array_of_array_is_not_supported() + { + return base.Array_of_array_is_not_supported(); + } + + [NotSupportedOnFirebirdFact] + public override Task Multidimensional_array_is_not_supported() + { + return base.Multidimensional_array_is_not_supported(); + } + + [NotSupportedOnFirebirdFact] + public override Task Column_with_custom_converter() + { + return base.Column_with_custom_converter(); + } + + [NotSupportedOnFirebirdFact] + public override Task Parameter_with_inferred_value_converter() + { + return base.Parameter_with_inferred_value_converter(); + } + + [NotSupportedOnFirebirdFact] + public override Task Constant_with_inferred_value_converter() + { + return base.Constant_with_inferred_value_converter(); + } + + [NotSupportedOnFirebirdFact] + public override Task Inline_collection_in_query_filter() + { + return base.Inline_collection_in_query_filter(); + } + + [NotSupportedOnFirebirdFact] + public override Task Column_collection_inside_json_owned_entity() + { + return base.Column_collection_inside_json_owned_entity(); + } + + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs index fe50eb71c..778d544bf 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindAggregateOperatorsQueryFbTest.cs @@ -15,6 +15,7 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using System; using System.Threading.Tasks; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; @@ -38,6 +39,24 @@ public override Task Multiple_collection_navigation_with_FirstOrDefault_chained( return base.Multiple_collection_navigation_with_FirstOrDefault_chained(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override async Task Contains_with_local_enumerable_inline(bool async) + { + await Assert.ThrowsAsync( + async () => + await base.Contains_with_local_enumerable_inline(async)); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override async Task Contains_with_local_enumerable_inline_closure_mix(bool async) + { + await Assert.ThrowsAsync( + async () => + await base.Contains_with_local_enumerable_inline_closure_mix(async)); + } + [Theory] [MemberData(nameof(IsAsyncData))] public override Task Contains_with_local_anonymous_type_array_closure(bool async) @@ -72,4 +91,11 @@ public override Task Sum_with_division_on_decimal(bool async) { return base.Sum_with_division_on_decimal(async); } + + [Theory(Skip = "Different math on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task Contains_inside_Average_without_GroupBy(bool async) + { + return base.Contains_inside_Average_without_GroupBy(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindChangeTrackingQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindChangeTrackingQueryFbTest.cs index b029cade2..eace4c3b5 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindChangeTrackingQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindChangeTrackingQueryFbTest.cs @@ -15,6 +15,7 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestModels.Northwind; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.Northwind; @@ -29,7 +30,7 @@ public NorthwindChangeTrackingQueryFbTest(NorthwindQueryFbFixture new NorthwindRelationalContext( + => new NorthwindFbContext( new DbContextOptionsBuilder(Fixture.CreateOptions()) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).Options); } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindCompiledQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindCompiledQueryFbTest.cs index d8b1e3e83..f8eaa9d2c 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindCompiledQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindCompiledQueryFbTest.cs @@ -15,15 +15,10 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using System; -using System.Linq; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Diagnostics; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; -using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; -using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; @@ -33,61 +28,15 @@ public NorthwindCompiledQueryFbTest(NorthwindQueryFbFixture : base(fixture) { } - [Fact] - public override void MakeBinary_does_not_throw_for_unsupported_operator() - { - Assert.Equal( - CoreStrings.TranslationFailed("DbSet() .Where(c => c.CustomerID == (string)(__parameters[0]))"), - Assert.Throws( - () => base.MakeBinary_does_not_throw_for_unsupported_operator()).Message.Replace("\r", "").Replace("\n", "")); - } - - [Fact] + [NotSupportedOnFirebirdFact] public override void Query_with_array_parameter() { - var query = EF.CompileQuery( - (NorthwindContext context, string[] args) - => context.Customers.Where(c => c.CustomerID == args[0])); - - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("DbSet() .Where(c => c.CustomerID == __args[0])"), - Assert.Throws( - () => query(context, new[] { "ALFKI" }).First().CustomerID).Message.Replace("\r", "").Replace("\n", "")); - } - - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("DbSet() .Where(c => c.CustomerID == __args[0])"), - Assert.Throws( - () => query(context, new[] { "ANATR" }).First().CustomerID).Message.Replace("\r", "").Replace("\n", "")); - } + base.Query_with_array_parameter(); } - [Fact] - public override async Task Query_with_array_parameter_async() + [NotSupportedOnFirebirdFact] + public override Task Query_with_array_parameter_async() { - var query = EF.CompileAsyncQuery( - (NorthwindContext context, string[] args) - => context.Customers.Where(c => c.CustomerID == args[0])); - - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("DbSet() .Where(c => c.CustomerID == __args[0])"), - (await Assert.ThrowsAsync( - () => Enumerate(query(context, new[] { "ALFKI" })))).Message.Replace("\r", "").Replace("\n", "")); - } - - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("DbSet() .Where(c => c.CustomerID == __args[0])"), - (await Assert.ThrowsAsync( - () => Enumerate(query(context, new[] { "ANATR" })))).Message.Replace("\r", "").Replace("\n", "")); - } + return base.Query_with_array_parameter_async(); } - } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs index d3ef9d563..13eb38b40 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindFunctionsQueryFbTest.cs @@ -108,6 +108,34 @@ public override Task TrimStart_with_char_array_argument_in_predicate(bool async) return base.TrimStart_with_char_array_argument_in_predicate(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Where_math_degrees(bool async) + { + return base.Where_math_degrees(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Where_math_radians(bool async) + { + return base.Where_mathf_radians(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Where_mathf_degrees(bool async) + { + return base.Where_math_degrees(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Where_mathf_radians(bool async) + { + return base.Where_mathf_radians(async); + } + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] public override Task Regex_IsMatch_MethodCall(bool async) @@ -268,18 +296,4 @@ public override Task Datetime_subtraction_TotalDays(bool async) { return base.Datetime_subtraction_TotalDays(async); } - - [Theory] - [MemberData(nameof(IsAsyncData))] - public override Task String_FirstOrDefault_MethodCall(bool async) - { - return base.String_FirstOrDefault_MethodCall(async); - } - - [Theory] - [MemberData(nameof(IsAsyncData))] - public override Task String_LastOrDefault_MethodCall(bool async) - { - return base.String_LastOrDefault_MethodCall(async); - } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs index 49609b886..f6fd3ffae 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs @@ -114,4 +114,11 @@ public override Task Unflattened_GroupJoin_composed_2(bool async) { return base.Unflattened_GroupJoin_composed_2(async); } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Join_local_collection_int_closure_is_cached_correctly(bool async) + { + return base.Join_local_collection_int_closure_is_cached_correctly(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs index b2fcee996..9a48b8376 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindMiscellaneousQueryFbTest.cs @@ -133,4 +133,18 @@ public override Task SelectMany_correlated_subquery_hard(bool async) { return base.SelectMany_correlated_subquery_hard(async); } + + [Theory(Skip = "Different implicit ordering on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task Entity_equality_orderby_subquery(bool async) + { + return base.Entity_equality_orderby_subquery(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Subquery_with_navigation_inside_inline_collection(bool async) + { + return base.Subquery_with_navigation_inside_inline_collection(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs index 5219a5cac..d6c6e7212 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindQueryFbFixture.cs @@ -22,6 +22,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsProceduralFbTest.cs similarity index 68% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbFixture.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsProceduralFbTest.cs index 81a30a962..1fdbc215d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceRelationshipsQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsProceduralFbTest.cs @@ -15,22 +15,13 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; -using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class InheritanceRelationshipsQueryFbFixture : InheritanceRelationshipsQueryRelationalFixture +public class OperatorsProceduralFbTest : OperatorsProceduralQueryTestBase { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; - - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) - { - base.OnModelCreating(modelBuilder, context); - ModelHelpers.SetPrimaryKeyGeneration(modelBuilder); - ModelHelpers.SimpleTableNames(modelBuilder); - } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs new file mode 100644 index 000000000..72a4473e5 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OperatorsQueryFbTest.cs @@ -0,0 +1,62 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System; +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class OperatorsQueryFbTest : OperatorsQueryTestBase +{ + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Concat_and_json_scalar(bool async) + { + return base.Concat_and_json_scalar(async); + } + + protected override ContextFactory Initialize(Action onModelCreating = null, Action onConfiguring = null, Action addServices = null, Action seed = null, Func shouldLogCategory = null, Func createTestStore = null, bool usePooling = true) + { + return base.Initialize( + modelBuilder => + { + ModelHelpers.SetStringLengths(modelBuilder); + onModelCreating?.Invoke(modelBuilder); + }, + onConfiguring, addServices, seed, shouldLogCategory, createTestStore, usePooling); + } + + protected override Task> InitializeAsync(Action onModelCreating = null, Action onConfiguring = null, Action addServices = null, Action seed = null, Func shouldLogCategory = null, Func createTestStore = null, bool usePooling = true) + { + return base.InitializeAsync( + modelBuilder => + { + ModelHelpers.SetStringLengths(modelBuilder); + onModelCreating?.Invoke(modelBuilder); + }, + onConfiguring, addServices, seed, shouldLogCategory, createTestStore, usePooling); + } + + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbFixture.cs new file mode 100644 index 000000000..337a447e7 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbFixture.cs @@ -0,0 +1,27 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class OptionalDependentQueryFbFixture : OptionalDependentQueryFixtureBase +{ + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbTest.cs new file mode 100644 index 000000000..72e33e6b0 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/OptionalDependentQueryFbTest.cs @@ -0,0 +1,100 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using Microsoft.EntityFrameworkCore.Query; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class OptionalDependentQueryFbTest : OptionalDependentQueryTestBase +{ + public OptionalDependentQueryFbTest(OptionalDependentQueryFbFixture fixture) + : base(fixture) + { } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Basic_projection_entity_with_all_optional(bool async) + { + return base.Basic_projection_entity_with_all_optional(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Basic_projection_entity_with_some_required(bool async) + { + return base.Basic_projection_entity_with_some_required(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_nested_optional_dependent_with_all_optional_compared_to_not_null(bool async) + { + return base.Filter_nested_optional_dependent_with_all_optional_compared_to_not_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_nested_optional_dependent_with_all_optional_compared_to_null(bool async) + { + return base.Filter_nested_optional_dependent_with_all_optional_compared_to_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_nested_optional_dependent_with_some_required_compared_to_not_null(bool async) + { + return base.Filter_nested_optional_dependent_with_some_required_compared_to_not_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_nested_optional_dependent_with_some_required_compared_to_null(bool async) + { + return base.Filter_nested_optional_dependent_with_some_required_compared_to_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_optional_dependent_with_all_optional_compared_to_not_null(bool async) + { + return base.Filter_optional_dependent_with_all_optional_compared_to_not_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_optional_dependent_with_all_optional_compared_to_null(bool async) + { + return base.Filter_optional_dependent_with_all_optional_compared_to_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_optional_dependent_with_some_required_compared_to_not_null(bool async) + { + return base.Filter_optional_dependent_with_some_required_compared_to_not_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Filter_optional_dependent_with_some_required_compared_to_null(bool async) + { + return base.Filter_optional_dependent_with_some_required_compared_to_null(async); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs new file mode 100644 index 000000000..8b800517d --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/PrimitiveCollectionsQueryFbTest.cs @@ -0,0 +1,481 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Threading.Tasks; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.TestUtilities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class PrimitiveCollectionsQueryFbTest : PrimitiveCollectionsQueryRelationalTestBase +{ + public PrimitiveCollectionsQueryFbTest(PrimitiveCollectionsQueryFbFixture fixture) + : base(fixture) + { } + + [ConditionalFact] + public virtual async Task Json_representation_of_bool_array() + { + await using var context = CreateContext(); + + Assert.Equal( + "[true,false]", + await context.Database.SqlQuery($@"SELECT ""Bools"" AS ""Value"" FROM ""PrimitiveCollectionsEntity"" WHERE ""Id"" = 1") + .SingleAsync()); + } + + [NotSupportedOnFirebirdFact] + public override void Parameter_collection_in_subquery_and_Convert_as_compiled_query() + { + base.Parameter_collection_in_subquery_and_Convert_as_compiled_query(); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_in_subquery_Union_another_parameter_collection_as_compiled_query(bool async) + { + return base.Parameter_collection_in_subquery_Union_another_parameter_collection_as_compiled_query(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_strings_contains_null(bool async) + { + return base.Column_collection_of_strings_contains_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Count_with_one_value(bool async) + { + return base.Inline_collection_Count_with_one_value(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Count_with_two_values(bool async) + { + return base.Inline_collection_Count_with_two_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Count_with_three_values(bool async) + { + return base.Inline_collection_Count_with_three_values(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_Count(bool async) + { + return base.Parameter_collection_Count(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_ints_Contains_int(bool async) + { + return base.Parameter_collection_of_ints_Contains_int(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_nullable_ints_Contains_int(bool async) + { + return base.Parameter_collection_of_nullable_ints_Contains_int(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_nullable_ints_Contains_nullable_int(bool async) + { + return base.Parameter_collection_of_nullable_ints_Contains_nullable_int(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_strings_Contains_string(bool async) + { + return base.Parameter_collection_of_strings_Contains_string(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_strings_Contains_nullable_string(bool async) + { + return base.Parameter_collection_of_strings_Contains_nullable_string(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_DateTimes_Contains(bool async) + { + return base.Parameter_collection_of_DateTimes_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_bools_Contains(bool async) + { + return base.Parameter_collection_of_bools_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_of_enums_Contains(bool async) + { + return base.Parameter_collection_of_enums_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_null_Contains(bool async) + { + return base.Parameter_collection_null_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_ints_Contains(bool async) + { + return base.Column_collection_of_ints_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_nullable_ints_Contains(bool async) + { + return base.Column_collection_of_nullable_ints_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_nullable_ints_Contains_null(bool async) + { + return base.Column_collection_of_nullable_ints_Contains_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_nullable_strings_contains_null(bool async) + { + return base.Column_collection_of_nullable_strings_contains_null(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_of_bools_Contains(bool async) + { + return base.Column_collection_of_bools_Contains(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Count_method(bool async) + { + return base.Column_collection_Count_method(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Length(bool async) + { + return base.Column_collection_Length(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_index_int(bool async) + { + return base.Column_collection_index_int(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_index_string(bool async) + { + return base.Column_collection_index_string(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_index_datetime(bool async) + { + return base.Column_collection_index_datetime(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_index_beyond_end(bool async) + { + return base.Column_collection_index_beyond_end(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Nullable_reference_column_collection_index_equals_nullable_column(bool async) + { + return base.Nullable_reference_column_collection_index_equals_nullable_column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Non_nullable_reference_column_collection_index_equals_nullable_column(bool async) + { + return base.Non_nullable_reference_column_collection_index_equals_nullable_column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_index_Column(bool async) + { + return base.Inline_collection_index_Column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_index_Column_equal_Column(bool async) + { + return base.Parameter_collection_index_Column_equal_Column(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_index_Column_equal_constant(bool async) + { + return base.Parameter_collection_index_Column_equal_constant(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_ElementAt(bool async) + { + return base.Column_collection_ElementAt(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Skip(bool async) + { + return base.Column_collection_Skip(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Take(bool async) + { + return base.Column_collection_Take(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Skip_Take(bool async) + { + return base.Column_collection_Skip_Take(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_OrderByDescending_ElementAt(bool async) + { + return base.Column_collection_OrderByDescending_ElementAt(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Any(bool async) + { + return base.Column_collection_Any(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Distinct(bool async) + { + return base.Column_collection_Distinct(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Join_parameter_collection(bool async) + { + return base.Column_collection_Join_parameter_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Join_ordered_column_collection(bool async) + { + return base.Inline_collection_Join_ordered_column_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_Concat_column_collection(bool async) + { + return base.Parameter_collection_Concat_column_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Union_parameter_collection(bool async) + { + return base.Column_collection_Union_parameter_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_Intersect_inline_collection(bool async) + { + return base.Column_collection_Intersect_inline_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Inline_collection_Except_column_collection(bool async) + { + return base.Inline_collection_Except_column_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_in_subquery_Union_column_collection_as_compiled_query(bool async) + { + return base.Parameter_collection_in_subquery_Union_column_collection_as_compiled_query(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_in_subquery_Union_column_collection(bool async) + { + return base.Parameter_collection_in_subquery_Union_column_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_in_subquery_Union_column_collection_nested(bool async) + { + return base.Parameter_collection_in_subquery_Union_column_collection_nested(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Parameter_collection_in_subquery_Count_as_compiled_query(bool async) + { + return base.Parameter_collection_in_subquery_Count_as_compiled_query(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Column_collection_in_subquery_Union_parameter_collection(bool async) + { + return base.Column_collection_in_subquery_Union_parameter_collection(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_ints_ordered(bool async) + { + return base.Project_collection_of_ints_ordered(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_datetimes_filtered(bool async) + { + return base.Project_collection_of_datetimes_filtered(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_nullable_ints_with_paging(bool async) + { + return base.Project_collection_of_nullable_ints_with_paging(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_nullable_ints_with_paging2(bool async) + { + return base.Project_collection_of_nullable_ints_with_paging2(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_nullable_ints_with_paging3(bool async) + { + return base.Project_collection_of_nullable_ints_with_paging3(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_collection_of_ints_with_distinct(bool async) + { + return base.Project_collection_of_ints_with_distinct(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_empty_collection_of_nullables_and_collection_only_containing_nulls(bool async) + { + return base.Project_empty_collection_of_nullables_and_collection_only_containing_nulls(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_multiple_collections(bool async) + { + return base.Project_multiple_collections(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Project_primitive_collections_element(bool async) + { + return base.Project_primitive_collections_element(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Nested_contains_with_Lists_and_no_inferred_type_mapping(bool async) + { + return base.Nested_contains_with_Lists_and_no_inferred_type_mapping(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Nested_contains_with_arrays_and_no_inferred_type_mapping(bool async) + { + return base.Nested_contains_with_arrays_and_no_inferred_type_mapping(async); + } + + PrimitiveCollectionsContext CreateContext() + { + return Fixture.CreateContext(); + } + + public class PrimitiveCollectionsQueryFbFixture : PrimitiveCollectionsQueryFixtureBase + { + protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/QueryFilterFuncletizationFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/QueryFilterFuncletizationFbTest.cs index f06645473..0713a9824 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/QueryFilterFuncletizationFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/QueryFilterFuncletizationFbTest.cs @@ -58,22 +58,7 @@ public override void DbContext_list_is_parameterized() var fbTestStore = (FbTestStore)Fixture.TestStore; if (fbTestStore.ServerLessThan4()) return; - - using var context = CreateContext(); - // Default value of TenantIds is null InExpression over null values throws - Assert.Throws(() => context.Set().ToList()); - - context.TenantIds = new List(); - var query = context.Set().ToList(); - Assert.Empty(query); - - context.TenantIds = new List { 1 }; - query = context.Set().ToList(); - Assert.Single(query); - - context.TenantIds = new List { 2, 3 }; - query = context.Set().ToList(); - Assert.Equal(2, query.Count); + base.DbContext_list_is_parameterized(); } [Fact] @@ -292,6 +277,15 @@ public override void Using_multiple_context_in_filter_parametrize_only_current_c base.Using_multiple_context_in_filter_parametrize_only_current_context(); } + [Fact] + public override void Using_multiple_entities_with_filters_reuses_parameters() + { + var fbTestStore = (FbTestStore)Fixture.TestStore; + if (fbTestStore.ServerLessThan4()) + return; + base.Using_multiple_entities_with_filters_reuses_parameters(); + } + public class QueryFilterFuncletizationFbFixture : QueryFilterFuncletizationRelationalFixture { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs index 0f7e53b5b..d852e8c1b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlExecutorFbTest.cs @@ -22,6 +22,7 @@ using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; @@ -38,39 +39,27 @@ protected override DbParameter CreateDbParameter(string name, object value) protected override string CustomerOrderHistorySproc => throw new NotSupportedException(); protected override string CustomerOrderHistoryWithGeneratedParameterSproc => throw new NotSupportedException(); - [DoesNotHaveTheDataFact] - public override void Executes_stored_procedure() + [DoesNotHaveTheDataTheory] + [InlineData(false)] + [InlineData(true)] + public override Task Executes_stored_procedure(bool async) { - base.Executes_stored_procedure(); + return base.Executes_stored_procedure(async); } - [DoesNotHaveTheDataFact] - public override Task Executes_stored_procedure_async() + [DoesNotHaveTheDataTheory] + [InlineData(false)] + [InlineData(true)] + public override Task Executes_stored_procedure_with_generated_parameter(bool async) { - return base.Executes_stored_procedure_async(); + return base.Executes_stored_procedure_with_generated_parameter(async); } - [DoesNotHaveTheDataFact] - public override void Executes_stored_procedure_with_generated_parameter() + [DoesNotHaveTheDataTheory] + [InlineData(false)] + [InlineData(true)] + public override Task Executes_stored_procedure_with_parameter(bool async) { - base.Executes_stored_procedure_with_generated_parameter(); - } - - [DoesNotHaveTheDataFact] - public override Task Executes_stored_procedure_with_generated_parameter_async() - { - return base.Executes_stored_procedure_with_generated_parameter_async(); - } - - [DoesNotHaveTheDataFact] - public override void Executes_stored_procedure_with_parameter() - { - base.Executes_stored_procedure_with_parameter(); - } - - [DoesNotHaveTheDataFact] - public override Task Executes_stored_procedure_with_parameter_async() - { - return base.Executes_stored_procedure_with_parameter_async(); + return base.Executes_stored_procedure_with_parameter(async); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs new file mode 100644 index 000000000..b5f827a2f --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/SqlQueryFbTest.cs @@ -0,0 +1,148 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Data.Common; +using System.Threading.Tasks; +using FirebirdSql.Data.FirebirdClient; +using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; + +public class SqlQueryFbTest : SqlQueryTestBase> +{ + public SqlQueryFbTest(NorthwindQueryFbFixture fixture) + : base(fixture) + { } + + [Theory(Skip = "Provider does the casting.")] + [MemberData(nameof(IsAsyncData))] + public override Task Bad_data_error_handling_invalid_cast(bool async) + { + return base.Bad_data_error_handling_invalid_cast(async); + } + + [Theory(Skip = "Provider does the casting.")] + [MemberData(nameof(IsAsyncData))] + public override Task Bad_data_error_handling_invalid_cast_key(bool async) + { + return base.Bad_data_error_handling_invalid_cast_key(async); + } + + [Theory(Skip = "Provider does the casting.")] + [MemberData(nameof(IsAsyncData))] + public override Task Bad_data_error_handling_invalid_cast_no_tracking(bool async) + { + return base.Bad_data_error_handling_invalid_cast_no_tracking(async); + } + + [Theory(Skip = "Provider does the casting.")] + [MemberData(nameof(IsAsyncData))] + public override Task Bad_data_error_handling_invalid_cast_projection(bool async) + { + return base.Bad_data_error_handling_invalid_cast_projection(async); + } + + [Theory(Skip = "Provider does the casting.")] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_simple_projection_composed(bool async) + { + return base.SqlQueryRaw_queryable_simple_projection_composed(async); + } + + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Multiple_occurrences_of_SqlQuery_with_db_parameter_adds_parameter_only_once(bool async) + { + return base.Multiple_occurrences_of_SqlQuery_with_db_parameter_adds_parameter_only_once(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_with_dbParameter_mixed_in_subquery(bool async) + { + return base.SqlQueryRaw_with_dbParameter_mixed_in_subquery(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_multiple_composed_with_parameters_and_closure_parameters(bool async) + { + return base.SqlQueryRaw_queryable_multiple_composed_with_parameters_and_closure_parameters(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_multiple_composed_with_closure_parameters(bool async) + { + return base.SqlQueryRaw_queryable_multiple_composed_with_closure_parameters(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_multiple_composed(bool async) + { + return base.SqlQueryRaw_queryable_multiple_composed(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_in_subquery_with_positional_dbParameter_without_name(bool async) + { + return base.SqlQueryRaw_in_subquery_with_positional_dbParameter_without_name(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_in_subquery_with_positional_dbParameter_with_name(bool async) + { + return base.SqlQueryRaw_in_subquery_with_positional_dbParameter_with_name(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_in_subquery_with_dbParameter(bool async) + { + return base.SqlQueryRaw_in_subquery_with_dbParameter(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_does_not_parameterize_interpolated_string(bool async) + { + return base.SqlQueryRaw_does_not_parameterize_interpolated_string(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQueryRaw_queryable_with_null_parameter(bool async) + { + return base.SqlQueryRaw_queryable_with_null_parameter(async); + } + + [DoesNotHaveTheDataTheory] + [MemberData(nameof(IsAsyncData))] + public override Task SqlQuery_queryable_multiple_composed_with_parameters_and_closure_parameters_interpolated(bool async) + { + return base.SqlQuery_queryable_multiple_composed_with_parameters_and_closure_parameters_interpolated(async); + } + + protected override DbParameter CreateDbParameter(string name, object value) + => new FbParameter { ParameterName = name, Value = value }; +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCFiltersInheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCFiltersInheritanceQueryFbFixture.cs index c3634770c..4ed46411a 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCFiltersInheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCFiltersInheritanceQueryFbFixture.cs @@ -19,5 +19,5 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPCFiltersInheritanceQueryFbFixture : TPCInheritanceQueryFbFixture { - protected override bool EnableFilters => true; + public override bool EnableFilters => true; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs index d93eab640..ef788f503 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCGearsOfWarQueryFbTest.cs @@ -20,7 +20,6 @@ using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; -using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; @@ -31,6 +30,31 @@ public TPCGearsOfWarQueryFbTest(TPCGearsOfWarQueryFbFixture fixture) : base(fixture) { } + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task ToString_boolean_property_non_nullable(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Select(w => w.IsAutomatic.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task ToString_boolean_property_nullable(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Select(lh => lh.Eradicated.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + } + + [Theory(Skip = "Different implicit ordering on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task Group_by_on_StartsWith_with_null_parameter_as_argument(bool async) + { + return base.Group_by_on_StartsWith_with_null_parameter_as_argument(async); + } + [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Array_access_on_byte_array(bool async) @@ -220,6 +244,13 @@ public override Task Subquery_projecting_nullable_scalar_contains_nullable_value return base.Subquery_projecting_nullable_scalar_contains_nullable_value_needs_null_expansion_negated(async); } + [NotSupportedOnFirebirdTheory] + [MemberData(nameof(IsAsyncData))] + public override Task Subquery_inside_Take_argument(bool async) + { + return base.Subquery_inside_Take_argument(async); + } + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] public override Task Where_DateOnly_AddDays(bool async) @@ -416,20 +447,18 @@ public override Task Where_TimeOnly_subtract_TimeOnly(bool async) return base.Where_TimeOnly_subtract_TimeOnly(async); } - [Theory] + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] - public override Task ToString_boolean_property_nullable(bool async) + public override Task DateTimeOffset_to_unix_time_milliseconds(bool async) { - return AssertQuery(async, (ISetSource ss) => from lh in ss.Set() - select ((object)lh.Eradicated).ToString(), null, elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.InvariantCultureIgnoreCase)); }, assertOrder: false, 0, "ToString_boolean_property_nullable"); + return base.DateTimeOffset_to_unix_time_milliseconds(async); } - [Theory] + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] - public override Task ToString_boolean_property_non_nullable(bool async) + public override Task DateTimeOffset_to_unix_time_seconds(bool async) { - return AssertQuery(async, (ISetSource ss) => from w in ss.Set() - select w.IsAutomatic.ToString(), null, elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.InvariantCultureIgnoreCase)); }, assertOrder: false, 0, "ToString_boolean_property_non_nullable"); + return base.DateTimeOffset_to_unix_time_seconds(async); } [Theory(Skip = "Different implicit ordering on Firebird.")] diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbFixture.cs index eb47f9bd4..c0a9d8d06 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbFixture.cs @@ -19,5 +19,5 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPCInheritanceQueryFbFixture : TPCInheritanceQueryFbFixtureBase { - protected override bool UseGeneratedKeys => true; + public override bool UseGeneratedKeys => true; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTest.cs index 36c293304..026610653 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTest.cs @@ -15,11 +15,13 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using Xunit.Abstractions; + namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPCInheritanceQueryFbTest : TPCInheritanceQueryFbTestBase { - public TPCInheritanceQueryFbTest(TPCInheritanceQueryFbFixture fixture) - : base(fixture) + public TPCInheritanceQueryFbTest(TPCInheritanceQueryFbFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTestBase.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTestBase.cs index 71ed94862..4f2630de3 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTestBase.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryFbTestBase.cs @@ -15,15 +15,15 @@ //$Authors = Jiri Cincura (jiri@cincura.net) -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; +using Xunit.Abstractions; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public abstract class TPCInheritanceQueryFbTestBase : TPCInheritanceQueryTestBase where TFixture : TPCInheritanceQueryFbFixtureBase, new() { - protected TPCInheritanceQueryFbTestBase(TFixture fixture) - : base(fixture) + protected TPCInheritanceQueryFbTestBase(TFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryHiLoFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryHiLoFbTest.cs index 1edcc7360..39a6d588d 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryHiLoFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPCInheritanceQueryHiLoFbTest.cs @@ -15,11 +15,13 @@ //$Authors = Jiri Cincura (jiri@cincura.net) +using Xunit.Abstractions; + namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPCInheritanceQueryHiLoFbTest : TPCInheritanceQueryFbTestBase { - public TPCInheritanceQueryHiLoFbTest(TPCInheritanceQueryHiLoFbFixture fixture) - : base(fixture) + public TPCInheritanceQueryHiLoFbTest(TPCInheritanceQueryHiLoFbFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbFixture.cs similarity index 85% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbFixture.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbFixture.cs index 7fcf769ec..e2e0ac7ca 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbFixture.cs @@ -17,7 +17,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class FiltersInheritanceQueryFbFixture : InheritanceQueryFbFixture +public class TPHFiltersInheritanceQueryFbFixture : TPHInheritanceQueryFbFixture { - protected override bool EnableFilters => true; + public override bool EnableFilters => true; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbTest.cs similarity index 79% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbTest.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbTest.cs index 714c79e5b..895bb9624 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/FiltersInheritanceQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHFiltersInheritanceQueryFbTest.cs @@ -19,9 +19,9 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class FiltersInheritanceQueryFbTest : FiltersInheritanceQueryTestBase +public class TPHFiltersInheritanceQueryFbTest : FiltersInheritanceQueryTestBase { - public FiltersInheritanceQueryFbTest(FiltersInheritanceQueryFbFixture fixture) + public TPHFiltersInheritanceQueryFbTest(TPHFiltersInheritanceQueryFbFixture fixture) : base(fixture) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbFixture.cs similarity index 94% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbFixture.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbFixture.cs index b1a9d94fe..b12c114b1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbFixture.cs @@ -23,7 +23,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class InheritanceQueryFbFixture : InheritanceQueryRelationalFixture +public class TPHInheritanceQueryFbFixture : TPHInheritanceQueryFixture { protected override ITestStoreFactory TestStoreFactory => FbTestStoreFactory.Instance; diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbTest.cs similarity index 74% rename from src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbTest.cs rename to src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbTest.cs index 33063a50a..3b50b792f 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/InheritanceQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPHInheritanceQueryFbTest.cs @@ -16,12 +16,13 @@ //$Authors = Jiri Cincura (jiri@cincura.net) using Microsoft.EntityFrameworkCore.Query; +using Xunit.Abstractions; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; -public class InheritanceQueryFbTest : InheritanceRelationalQueryTestBase +public class TPHInheritanceQueryFbTest : TPHInheritanceQueryTestBase { - public InheritanceQueryFbTest(InheritanceQueryFbFixture fixture) - : base(fixture) + public TPHInheritanceQueryFbTest(TPHInheritanceQueryFbFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTFiltersInheritanceQueryFbFixture.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTFiltersInheritanceQueryFbFixture.cs index 056de0575..81ad223b0 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTFiltersInheritanceQueryFbFixture.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTFiltersInheritanceQueryFbFixture.cs @@ -22,7 +22,7 @@ namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPTFiltersInheritanceQueryFbFixture : TPTInheritanceQueryFbFixture { - protected override bool EnableFilters => true; + public override bool EnableFilters => true; protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs index 3f0dc80d6..62886174e 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTGearsOfWarQueryFbTest.cs @@ -20,7 +20,6 @@ using FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; -using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; @@ -31,6 +30,31 @@ public TPTGearsOfWarQueryFbTest(TPTGearsOfWarQueryFbFixture fixture) : base(fixture) { } + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task ToString_boolean_property_non_nullable(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Select(w => w.IsAutomatic.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + } + + [Theory] + [MemberData(nameof(IsAsyncData))] + public override Task ToString_boolean_property_nullable(bool async) + { + return AssertQuery( + async, + ss => ss.Set().Select(lh => lh.Eradicated.ToString()), elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.OrdinalIgnoreCase)); }); + } + + [Theory(Skip = "Different implicit ordering on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task Group_by_on_StartsWith_with_null_parameter_as_argument(bool async) + { + return base.Group_by_on_StartsWith_with_null_parameter_as_argument(async); + } + [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] public override Task Correlated_collections_inner_subquery_predicate_references_outer_qsre(bool async) @@ -297,41 +321,46 @@ public override Task First_on_byte_array(bool async) return base.First_on_byte_array(async); } - [Theory] + [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] - public override Task ToString_boolean_property_nullable(bool async) + public override Task Where_TimeOnly_subtract_TimeOnly(bool async) { - return AssertQuery(async, (ISetSource ss) => from lh in ss.Set() - select ((object)lh.Eradicated).ToString(), null, elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.InvariantCultureIgnoreCase)); }, assertOrder: false, 0, "ToString_boolean_property_nullable"); + return base.Where_TimeOnly_subtract_TimeOnly(async); } - [Theory] + [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] - public override Task ToString_boolean_property_non_nullable(bool async) + public override Task Correlated_collection_with_groupby_with_complex_grouping_key_not_projecting_identifier_column_with_group_aggregate_in_final_projection(bool async) { - return AssertQuery(async, (ISetSource ss) => from w in ss.Set() - select w.IsAutomatic.ToString(), null, elementAsserter: (lhs, rhs) => { Assert.True(lhs.Equals(rhs, System.StringComparison.InvariantCultureIgnoreCase)); }, assertOrder: false, 0, "ToString_boolean_property_non_nullable"); + return base.Correlated_collection_with_groupby_with_complex_grouping_key_not_projecting_identifier_column_with_group_aggregate_in_final_projection(async); } [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] - public override Task Where_TimeOnly_subtract_TimeOnly(bool async) + public override Task DateTimeOffsetNow_minus_timespan(bool async) { - return base.Where_TimeOnly_subtract_TimeOnly(async); + return base.DateTimeOffsetNow_minus_timespan(async); } [NotSupportedOnFirebirdTheory] [MemberData(nameof(IsAsyncData))] - public override Task Correlated_collection_with_groupby_with_complex_grouping_key_not_projecting_identifier_column_with_group_aggregate_in_final_projection(bool async) + public override Task Subquery_inside_Take_argument(bool async) { - return base.Correlated_collection_with_groupby_with_complex_grouping_key_not_projecting_identifier_column_with_group_aggregate_in_final_projection(async); + return base.Subquery_inside_Take_argument(async); } - [NotSupportedOnFirebirdTheory] + [NotSupportedByProviderTheory] [MemberData(nameof(IsAsyncData))] - public override Task DateTimeOffsetNow_minus_timespan(bool async) + public override Task DateTimeOffset_to_unix_time_milliseconds(bool async) { - return base.DateTimeOffsetNow_minus_timespan(async); + return base.DateTimeOffset_to_unix_time_milliseconds(async); + } + + [NotSupportedByProviderTheory] + [MemberData(nameof(IsAsyncData))] + public override Task DateTimeOffset_to_unix_time_seconds(bool async) + { + return base.DateTimeOffset_to_unix_time_seconds(async); } [Theory(Skip = "NETProvider#1008")] @@ -347,4 +376,11 @@ public override Task Where_TimeOnly_Add_TimeSpan(bool async) { return base.Where_TimeOnly_Add_TimeSpan(async); } + + [Theory(Skip = "Different implicit ordering on Firebird.")] + [MemberData(nameof(IsAsyncData))] + public override Task String_concat_with_null_conditional_argument(bool async) + { + return base.String_concat_with_null_conditional_argument(async); + } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTInheritanceQueryFbTest.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTInheritanceQueryFbTest.cs index c7e3a46a4..f6fa61657 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTInheritanceQueryFbTest.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/TPTInheritanceQueryFbTest.cs @@ -16,12 +16,13 @@ //$Authors = Jiri Cincura (jiri@cincura.net) using Microsoft.EntityFrameworkCore.Query; +using Xunit.Abstractions; namespace FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.Query; public class TPTInheritanceQueryFbTest : TPTInheritanceQueryTestBase { - public TPTInheritanceQueryFbTest(TPTInheritanceQueryFbFixture fixture) - : base(fixture) + public TPTInheritanceQueryFbTest(TPTInheritanceQueryFbFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture, testOutputHelper) { } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs index 7d201a95d..fc05c2bf5 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs @@ -176,18 +176,6 @@ public override void QF_CrossJoin_Parameter() base.QF_CrossJoin_Parameter(); } - [Fact(Skip = "efcore#24228")] - public override void Nullable_navigation_property_access_preserves_schema_for_sql_function() - { - base.Nullable_navigation_property_access_preserves_schema_for_sql_function(); - } - - [Fact(Skip = "efcore#24228")] - public override void Compare_function_without_null_propagation_to_null() - { - base.Compare_function_without_null_propagation_to_null(); - } - protected class FbUDFSqlContext : UDFSqlContext { public FbUDFSqlContext(DbContextOptions options) @@ -319,6 +307,47 @@ returns boolean return true; end"); + context.Database.ExecuteSqlRaw( + @"create procedure ""GetTopTwoSellingProducts"" + returns + ( + ""ProductId"" int not null, + ""AmountSold"" int + ) + as + begin + for select first 2 ""ProductId"", sum(""Quantity"") as ""TotalSold"" + from ""LineItem"" + group by ""ProductId"" + order by ""TotalSold"" desc + into :""ProductId"", :""AmountSold"" do + begin + suspend; + end + end"); + + context.Database.ExecuteSqlRaw( + @"create procedure ""GetOrdersWithMultipleProducts""(customerId int) + returns + ( + ""OrderId"" int not null, + ""CustomerId"" int not null, + ""OrderDate"" timestamp + ) + as + begin + for select o.""Id"", :customerId, ""OrderDate"" + from ""Orders"" o + join ""LineItem"" li on o.""Id"" = li.""OrderId"" + where o.""CustomerId"" = :customerId + group by o.""Id"", ""OrderDate"" + having count(""ProductId"") > 1 + into :""OrderId"", :""CustomerId"", :""OrderDate"" do + begin + suspend; + end + end"); + context.SaveChanges(); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj index bc068fe0d..ce3ed3f3b 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/FirebirdSql.EntityFrameworkCore.Firebird.Tests.csproj @@ -18,7 +18,6 @@ - diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Migrations/MigrationsTests.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Migrations/MigrationsTests.cs index cc9aaf8a9..eabcd1bcc 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Migrations/MigrationsTests.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Migrations/MigrationsTests.cs @@ -624,7 +624,20 @@ public async Task RestartSequence() }; var batch = await Generate(new[] { operation }); Assert.AreEqual(1, batch.Count()); - Assert.AreEqual(NewLineEnd(@"ALTER SEQUENCE ""MySequence"" START WITH 23;"), batch[0].CommandText); + Assert.AreEqual(NewLineEnd(@"ALTER SEQUENCE ""MySequence"" RESTART WITH 23;"), batch[0].CommandText); + } + + [Test] + public async Task RestartSequenceNoValue() + { + var operation = new RestartSequenceOperation() + { + Name = "MySequence", + StartValue = null, + }; + var batch = await Generate(new[] { operation }); + Assert.AreEqual(1, batch.Count()); + Assert.AreEqual(NewLineEnd(@"ALTER SEQUENCE ""MySequence"" RESTART;"), batch[0].CommandText); } [Test] diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbPropertyExtensions.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbPropertyExtensions.cs index 85ab07c86..dc76ff76f 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbPropertyExtensions.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbPropertyExtensions.cs @@ -41,7 +41,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IPropert return FbValueGenerationStrategy.None; } - var modelStrategy = property.DeclaringEntityType.Model.GetValueGenerationStrategy(); + var modelStrategy = property.DeclaringType.Model.GetValueGenerationStrategy(); if (modelStrategy == FbValueGenerationStrategy.SequenceTrigger && IsCompatibleSequenceTrigger(property)) { @@ -49,7 +49,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IPropert } if (modelStrategy == FbValueGenerationStrategy.IdentityColumn) { - if (property.DeclaringEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) + if (property.DeclaringType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) { return FbValueGenerationStrategy.SequenceTrigger; } @@ -83,7 +83,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IMutable return FbValueGenerationStrategy.None; } - var modelStrategy = property.DeclaringEntityType.Model.GetValueGenerationStrategy(); + var modelStrategy = property.DeclaringType.Model.GetValueGenerationStrategy(); if (modelStrategy == FbValueGenerationStrategy.SequenceTrigger && IsCompatibleSequenceTrigger(property)) { @@ -91,7 +91,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IMutable } if (modelStrategy == FbValueGenerationStrategy.IdentityColumn) { - if (property.DeclaringEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) + if (property.DeclaringType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) { return FbValueGenerationStrategy.SequenceTrigger; } @@ -125,7 +125,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IConvent return FbValueGenerationStrategy.None; } - var modelStrategy = property.DeclaringEntityType.Model.GetValueGenerationStrategy(); + var modelStrategy = property.DeclaringType.Model.GetValueGenerationStrategy(); if (modelStrategy == FbValueGenerationStrategy.SequenceTrigger && IsCompatibleSequenceTrigger(property)) { @@ -133,7 +133,7 @@ public static FbValueGenerationStrategy GetValueGenerationStrategy(this IConvent } if (modelStrategy == FbValueGenerationStrategy.IdentityColumn) { - if (property.DeclaringEntityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) + if (property.DeclaringType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) { return FbValueGenerationStrategy.SequenceTrigger; } @@ -231,7 +231,7 @@ public static string SetHiLoSequenceSchema(this IConventionProperty property, st public static IReadOnlySequence FindHiLoSequence(this IReadOnlyProperty property) { - var model = property.DeclaringEntityType.Model; + var model = property.DeclaringType.Model; var sequenceName = property.GetHiLoSequenceName() ?? model.GetHiLoSequenceName(); @@ -244,7 +244,7 @@ public static IReadOnlySequence FindHiLoSequence(this IReadOnlyProperty property public static IReadOnlySequence FindHiLoSequence(this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { - var model = property.DeclaringEntityType.Model; + var model = property.DeclaringType.Model; var sequenceName = property.GetHiLoSequenceName(storeObject) ?? model.GetHiLoSequenceName(); @@ -329,7 +329,7 @@ public static string SetSequenceSchema(this IConventionProperty property, string public static IReadOnlySequence FindSequence(this IReadOnlyProperty property) { - var model = property.DeclaringEntityType.Model; + var model = property.DeclaringType.Model; var sequenceName = property.GetSequenceName() ?? model.GetSequenceNameSuffix(); @@ -342,7 +342,7 @@ public static IReadOnlySequence FindSequence(this IReadOnlyProperty property) public static IReadOnlySequence FindSequence(this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { - var model = property.DeclaringEntityType.Model; + var model = property.DeclaringType.Model; var sequenceName = property.GetSequenceName(storeObject) ?? model.GetSequenceNameSuffix(); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbServiceCollectionExtensions.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbServiceCollectionExtensions.cs index 505eeb563..787148fff 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbServiceCollectionExtensions.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Extensions/FbServiceCollectionExtensions.cs @@ -78,6 +78,7 @@ public static IServiceCollection AddEntityFrameworkFirebird(this IServiceCollect .TryAdd() .TryAdd() .TryAdd() + .TryAdd() .TryAdd() .TryAdd(p => p.GetService()) .TryAdd() diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/FirebirdSql.EntityFrameworkCore.Firebird.csproj b/src/FirebirdSql.EntityFrameworkCore.Firebird/FirebirdSql.EntityFrameworkCore.Firebird.csproj index b67d78537..69d85f5c2 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/FirebirdSql.EntityFrameworkCore.Firebird.csproj +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/FirebirdSql.EntityFrameworkCore.Firebird.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 FirebirdSql.EntityFrameworkCore.Firebird FirebirdSql.EntityFrameworkCore.Firebird true @@ -9,6 +9,7 @@ true + $(EFCoreProviderVersion) NETProvider - Entity Framework Core Provider (c) 2017-$(CopyrightEndYear) @@ -29,9 +30,12 @@ - + - + + + + diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/FbMigrationsSqlGenerator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/FbMigrationsSqlGenerator.cs index fb0b3f91a..746b65945 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/FbMigrationsSqlGenerator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Migrations/FbMigrationsSqlGenerator.cs @@ -272,8 +272,12 @@ protected override void Generate(RestartSequenceOperation operation, IModel mode { builder.Append("ALTER SEQUENCE "); builder.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name, operation.Schema)); - builder.Append(" START WITH "); - builder.Append(operation.StartValue.ToString(CultureInfo.InvariantCulture)); + builder.Append(" RESTART"); + if (operation.StartValue != null) + { + builder.Append(" WITH "); + builder.Append(((long)operation.StartValue).ToString(CultureInfo.InvariantCulture)); + } TerminateStatement(builder); } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs new file mode 100644 index 000000000..05dd34f40 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbDateOnlyMethodTranslator.cs @@ -0,0 +1,66 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Query.SqlExpressions; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.ExpressionTranslators.Internal; + +public class SqlServerDateOnlyMethodTranslator : IMethodCallTranslator +{ + readonly Dictionary _methodInfoDatePartMapping = new() + { + { typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddYears), [typeof(int)]), "year" }, + { typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddMonths), [typeof(int)]), "month" }, + { typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddDays), [typeof(int)]), "day" } + }; + + readonly ISqlExpressionFactory _sqlExpressionFactory; + + public SqlServerDateOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) + { + _sqlExpressionFactory = sqlExpressionFactory; + } + + public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) + { + if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart) && instance != null) + { + instance = _sqlExpressionFactory.ApplyDefaultTypeMapping(instance); + + return _sqlExpressionFactory.Function( + "DATEADD", + new[] { _sqlExpressionFactory.Fragment(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance }, + nullable: true, + argumentsPropagateNullability: new[] { false, true, true }, + instance.Type, + instance.TypeMapping); + } + + if (method.DeclaringType == typeof(DateOnly) && method.Name == nameof(DateOnly.FromDateTime) && arguments.Count == 1) + { + return _sqlExpressionFactory.Convert(arguments[0], typeof(DateOnly)); + } + + return null; + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringContainsTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringContainsTranslator.cs index 87ec77169..bc1905ad9 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringContainsTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringContainsTranslator.cs @@ -50,14 +50,15 @@ public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadO new[] { true, true }, typeof(int)), _fbSqlExpressionFactory.Constant(0)); - return patternExpression is SqlConstantExpression sqlConstantExpression + var matchingExpression = patternExpression is SqlConstantExpression sqlConstantExpression ? ((string)sqlConstantExpression.Value)?.Length == 0 ? (SqlExpression)_fbSqlExpressionFactory.Constant(true) - : positionExpression + : (SqlExpression)positionExpression : _fbSqlExpressionFactory.OrElse( positionExpression, _fbSqlExpressionFactory.Equal( _fbSqlExpressionFactory.Function("CHAR_LENGTH", new[] { patternExpression }, true, new[] { true }, typeof(int)), _fbSqlExpressionFactory.Constant(0))); + return _fbSqlExpressionFactory.AndAlso(matchingExpression, _fbSqlExpressionFactory.AndAlso(_fbSqlExpressionFactory.IsNotNull(instance), _fbSqlExpressionFactory.IsNotNull(patternExpression))); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringEndsWithTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringEndsWithTranslator.cs index a0353c0d6..0ddb1cdb1 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringEndsWithTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringEndsWithTranslator.cs @@ -57,14 +57,13 @@ public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadO new[] { true, true }, instance.Type)), patternExpression); - return patternExpression is SqlConstantExpression sqlConstantExpression - ? (string)sqlConstantExpression.Value == string.Empty - ? (SqlExpression)_fbSqlExpressionFactory.Constant(true) - : endsWithExpression - : _fbSqlExpressionFactory.OrElse( + var matchingExpression = patternExpression is SqlConstantExpression sqlConstantExpression + ? (SqlExpression)((string)sqlConstantExpression.Value == string.Empty ? (SqlExpression)_fbSqlExpressionFactory.Constant(true) : endsWithExpression) + : (SqlExpression)_fbSqlExpressionFactory.OrElse( endsWithExpression, _fbSqlExpressionFactory.Equal( _fbSqlExpressionFactory.Function("CHAR_LENGTH", new[] { patternExpression }, true, new[] { true }, typeof(int)), _fbSqlExpressionFactory.Constant(0))); + return _fbSqlExpressionFactory.AndAlso(matchingExpression, _fbSqlExpressionFactory.AndAlso(_fbSqlExpressionFactory.IsNotNull(instance), _fbSqlExpressionFactory.IsNotNull(patternExpression))); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringStartsWithTranslator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringStartsWithTranslator.cs index b89294c30..0608835be 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringStartsWithTranslator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/ExpressionTranslators/Internal/FbStringStartsWithTranslator.cs @@ -65,14 +65,13 @@ public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadO new[] { true, true }, instance.Type)), patternExpression)); - return patternConstantExpression != null - ? (string)patternConstantExpression.Value == string.Empty - ? _fbSqlExpressionFactory.Constant(true) - : startsWithExpression - : _fbSqlExpressionFactory.OrElse( + var matchingExpression = patternConstantExpression != null + ? (SqlExpression)((string)patternConstantExpression.Value == string.Empty ? _fbSqlExpressionFactory.Constant(true) : startsWithExpression) + : (SqlExpression)_fbSqlExpressionFactory.OrElse( startsWithExpression, _fbSqlExpressionFactory.Equal( _fbSqlExpressionFactory.Function("CHAR_LENGTH", new[] { patternExpression }, true, new[] { true }, typeof(int)), _fbSqlExpressionFactory.Constant(0))); + return _fbSqlExpressionFactory.AndAlso(matchingExpression, _fbSqlExpressionFactory.AndAlso(_fbSqlExpressionFactory.IsNotNull(instance), _fbSqlExpressionFactory.IsNotNull(patternExpression))); } } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryRootProcessor.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryRootProcessor.cs new file mode 100644 index 000000000..495717e39 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryRootProcessor.cs @@ -0,0 +1,33 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore.Query; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.Internal; + +public class FbQueryRootProcessor : RelationalQueryRootProcessor +{ + public FbQueryRootProcessor(QueryTranslationPreprocessorDependencies dependencies, RelationalQueryTranslationPreprocessorDependencies relationalDependencies, QueryCompilationContext queryCompilationContext) + : base(dependencies, relationalDependencies, queryCompilationContext) + { } + + protected override bool ShouldConvertToParameterQueryRoot(ParameterExpression constantExpression) + { + return false; + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs index 51268e4f3..c8f203bff 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs @@ -65,31 +65,64 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres Sql.Append(")"); return sqlBinaryExpression; } - else if (sqlBinaryExpression.OperatorType == ExpressionType.And && sqlBinaryExpression.TypeMapping.ClrType != typeof(bool)) + else if (sqlBinaryExpression.OperatorType == ExpressionType.And) { - Sql.Append("BIN_AND("); - Visit(sqlBinaryExpression.Left); - Sql.Append(", "); - Visit(sqlBinaryExpression.Right); - Sql.Append(")"); + if (sqlBinaryExpression.TypeMapping.ClrType == typeof(bool)) + { + Sql.Append("IIF(BIN_AND("); + BooleanToIntegralAndVisit(sqlBinaryExpression.Left); + Sql.Append(", "); + BooleanToIntegralAndVisit(sqlBinaryExpression.Right); + Sql.Append(") = 0, FALSE, TRUE)"); + } + else + { + Sql.Append("BIN_AND("); + Visit(sqlBinaryExpression.Left); + Sql.Append(", "); + Visit(sqlBinaryExpression.Right); + Sql.Append(")"); + } return sqlBinaryExpression; } - else if (sqlBinaryExpression.OperatorType == ExpressionType.Or && sqlBinaryExpression.TypeMapping.ClrType != typeof(bool)) + else if (sqlBinaryExpression.OperatorType == ExpressionType.Or) { - Sql.Append("BIN_OR("); - Visit(sqlBinaryExpression.Left); - Sql.Append(", "); - Visit(sqlBinaryExpression.Right); - Sql.Append(")"); + if (sqlBinaryExpression.TypeMapping.ClrType == typeof(bool)) + { + Sql.Append("IIF(BIN_OR("); + BooleanToIntegralAndVisit(sqlBinaryExpression.Left); + Sql.Append(", "); + BooleanToIntegralAndVisit(sqlBinaryExpression.Right); + Sql.Append(") = 0, FALSE, TRUE)"); + } + else + { + Sql.Append("BIN_OR("); + Visit(sqlBinaryExpression.Left); + Sql.Append(", "); + Visit(sqlBinaryExpression.Right); + Sql.Append(")"); + } return sqlBinaryExpression; } else if (sqlBinaryExpression.OperatorType == ExpressionType.ExclusiveOr) { - Sql.Append("BIN_XOR("); - Visit(sqlBinaryExpression.Left); - Sql.Append(", "); - Visit(sqlBinaryExpression.Right); - Sql.Append(")"); + if (sqlBinaryExpression.TypeMapping.ClrType == typeof(bool)) + { + Sql.Append("IIF(BIN_XOR("); + BooleanToIntegralAndVisit(sqlBinaryExpression.Left); + Sql.Append(", "); + BooleanToIntegralAndVisit(sqlBinaryExpression.Right); + Sql.Append(") = 0, FALSE, TRUE)"); + } + else + { + Sql.Append("BIN_XOR("); + Visit(sqlBinaryExpression.Left); + Sql.Append(", "); + Visit(sqlBinaryExpression.Right); + Sql.Append(")"); + } return sqlBinaryExpression; } else if (sqlBinaryExpression.OperatorType == ExpressionType.LeftShift) @@ -114,6 +147,13 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres { return base.VisitSqlBinary(sqlBinaryExpression); } + + void BooleanToIntegralAndVisit(SqlExpression expression) + { + Sql.Append("IIF("); + Visit(expression); + Sql.Append(", 1, 0)"); + } } protected override Expression VisitSqlParameter(SqlParameterExpression sqlParameterExpression) diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessor.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessor.cs new file mode 100644 index 000000000..d95a444af --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessor.cs @@ -0,0 +1,34 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore.Query; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.Internal; + +public class FbQueryTranslationPreprocessor : RelationalQueryTranslationPreprocessor +{ + public FbQueryTranslationPreprocessor(QueryTranslationPreprocessorDependencies dependencies, RelationalQueryTranslationPreprocessorDependencies relationalDependencies, QueryCompilationContext queryCompilationContext) + : base(dependencies, relationalDependencies, queryCompilationContext) + { } + + protected override Expression ProcessQueryRoots(Expression expression) + { + return new FbQueryRootProcessor(Dependencies, RelationalDependencies, QueryCompilationContext) + .Visit(expression); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessorFactory.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessorFactory.cs new file mode 100644 index 000000000..ebc6092e0 --- /dev/null +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQueryTranslationPreprocessorFactory.cs @@ -0,0 +1,37 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * https://github.com/FirebirdSQL/NETProvider/raw/master/license.txt. + * + * Software distributed under the License is distributed on + * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * All Rights Reserved. + */ + +//$Authors = Jiri Cincura (jiri@cincura.net) + +using Microsoft.EntityFrameworkCore.Query; + +namespace FirebirdSql.EntityFrameworkCore.Firebird.Query.Internal; + +public class FbQueryTranslationPreprocessorFactory : IQueryTranslationPreprocessorFactory +{ + readonly QueryTranslationPreprocessorDependencies _dependecies; + readonly RelationalQueryTranslationPreprocessorDependencies _relationalDependencies; + + public FbQueryTranslationPreprocessorFactory(QueryTranslationPreprocessorDependencies dependecies, RelationalQueryTranslationPreprocessorDependencies relationalDependencies) + { + _dependecies = dependecies; + _relationalDependencies = relationalDependencies; + } + + public QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext) + { + return new FbQueryTranslationPreprocessor(_dependecies, _relationalDependencies, queryCompilationContext); + } +} diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTypeMappingSource.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTypeMappingSource.cs index e4d85de9c..9e41a9efb 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTypeMappingSource.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTypeMappingSource.cs @@ -168,7 +168,7 @@ RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingInfo) var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? 256 : (int?)null); var maxSize = isUnicode ? UnicodeVarcharMaxSize : VarcharMaxSize; - if (size > maxSize) + if (size < 0 || size > maxSize) { size = isFixedLength ? maxSize : (int?)null; } diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorCache.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorCache.cs index 1eb45a3a5..7c7137519 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorCache.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorCache.cs @@ -33,7 +33,7 @@ public FbValueGeneratorCache(ValueGeneratorCacheDependencies dependencies) public virtual FbSequenceValueGeneratorState GetOrAddSequenceState(IProperty property, IRelationalConnection connection) { - var tableIdentifier = StoreObjectIdentifier.Create(property.DeclaringEntityType, StoreObjectType.Table); + var tableIdentifier = StoreObjectIdentifier.Create(property.DeclaringType, StoreObjectType.Table); var sequence = tableIdentifier != null ? property.FindHiLoSequence(tableIdentifier.Value) : property.FindHiLoSequence(); diff --git a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs index 7f80548f4..dd01a34dc 100644 --- a/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs +++ b/src/FirebirdSql.EntityFrameworkCore.Firebird/ValueGeneration/Internal/FbValueGeneratorSelector.cs @@ -44,7 +44,7 @@ public FbValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies, public new virtual IFbValueGeneratorCache Cache => (IFbValueGeneratorCache)base.Cache; - public override ValueGenerator Select(IProperty property, IEntityType entityType) + public override ValueGenerator Select(IProperty property, ITypeBase entityType) { if (property.GetValueGeneratorFactory() != null || property.GetValueGenerationStrategy() != FbValueGenerationStrategy.HiLo) @@ -87,10 +87,10 @@ public override ValueGenerator Select(IProperty property, IEntityType entityType throw new ArgumentException( CoreStrings.InvalidValueGeneratorFactoryProperty( - nameof(FbSequenceValueGeneratorFactory), property.Name, property.DeclaringEntityType.DisplayName())); + nameof(FbSequenceValueGeneratorFactory), property.Name, property.DeclaringType.DisplayName())); } - protected override ValueGenerator FindForType(IProperty property, IEntityType entityType, Type clrType) + protected override ValueGenerator FindForType(IProperty property, ITypeBase entityType, Type clrType) => property.ClrType.UnwrapNullableType() == typeof(Guid) ? property.ValueGenerated == ValueGenerated.Never || property.GetDefaultValueSql() != null ? new TemporaryGuidValueGenerator() diff --git a/src/NETProvider.sln b/src/NETProvider.sln index c7e674105..6c41c6e38 100644 --- a/src/NETProvider.sln +++ b/src/NETProvider.sln @@ -27,6 +27,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C68C23A7-AACE-4335-88F8-1060EDAB2131}" ProjectSection(SolutionItems) = preProject Directory.Build.props = Directory.Build.props + Versions.props = Versions.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests", "FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests\FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests.csproj", "{2925DB97-5B39-4D9E-90CC-F7470F9AA8F3}" @@ -39,7 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{CE2BB2BB-4 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scratchpad", "Scratchpad", "{5F1D1BB9-4657-424C-B3DE-75818824940E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scratchpad", "Scratchpad\Scratchpad.csproj", "{C3F47B3D-FA1F-4665-A58D-63B6FFDCD65F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scratchpad", "Scratchpad\Scratchpad.csproj", "{C3F47B3D-FA1F-4665-A58D-63B6FFDCD65F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Versions.props b/src/Versions.props new file mode 100644 index 000000000..1f220849b --- /dev/null +++ b/src/Versions.props @@ -0,0 +1,18 @@ + + + + 10.0.0 + + + + 11.0.0-beta2 + 10.0.0 + 8.0.4 + + + + 10.0.0 + 10.0.0 + 6.4.4 + + diff --git a/tests.ps1 b/tests.ps1 index 391a9bee3..b293410ca 100644 --- a/tests.ps1 +++ b/tests.ps1 @@ -29,8 +29,9 @@ $FirebirdConfiguration = @{ } } +$frameworkVersion = 'net8.0' $testsBaseDir = "$baseDir\src\FirebirdSql.Data.FirebirdClient.Tests" -$testsProviderDir = "$testsBaseDir\bin\$Configuration\$(Get-UsedTargetFramework)" +$testsProviderDir = "$testsBaseDir\bin\$Configuration\$frameworkVersion" $firebirdProcess = $null @@ -131,7 +132,7 @@ function Tests-FirebirdClient($serverType, $compression, $wireCrypt) { } function Tests-EF6() { - pushd "$baseDir\src\EntityFramework.Firebird.Tests\bin\$Configuration\$(Get-UsedTargetFramework)" + pushd "$baseDir\src\EntityFramework.Firebird.Tests\bin\$Configuration\$frameworkVersion" try { .\EntityFramework.Firebird.Tests.exe --labels=All Check-ExitCode @@ -142,7 +143,7 @@ function Tests-EF6() { } function Tests-EFCore() { - pushd "$baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird.Tests\bin\$Configuration\$(Get-UsedTargetFramework)" + pushd "$baseDir\src\FirebirdSql.EntityFrameworkCore.Firebird.Tests\bin\$Configuration\$frameworkVersion" try { .\FirebirdSql.EntityFrameworkCore.Firebird.Tests.exe --labels=All Check-ExitCode