From 63581903c6330026ab2569e303af3cdc25ee6e84 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 12 Feb 2026 10:23:38 +0100 Subject: [PATCH 1/2] Allow query test classes to have non-shared tests Closes #33526 --- ...aredPrimitiveCollectionsQueryCosmosTest.cs | 395 ------ .../PrimitiveCollectionsQueryCosmosTest.cs | 246 ++-- .../ReadItemPartitionKeyQueryFixtureBase.cs | 13 +- .../Types/CosmosMiscellaneousTypeTest.cs | 21 + .../Types/CosmosNumericTypeTest.cs | 4 + .../RelationalAssociationsTests.cs | 4 +- ...itiveCollectionsQueryRelationalTestBase.cs | 255 ---- .../Query/NullSemanticsQueryFixtureBase.cs | 10 +- .../OptionalDependentQueryFixtureBase.cs | 12 +- ...itiveCollectionsQueryRelationalTestBase.cs | 241 +++- .../JsonTranslationsRelationalTestBase.cs | 10 +- .../RelationalComplianceTestBase.cs | 6 +- .../TestUtilities/BulkUpdatesAsserter.cs | 4 +- .../Types/RelationalTypeFixtureBase.cs | 1 + .../BulkUpdates/BulkUpdatesTestBase.cs | 2 +- .../BulkUpdates/IBulkUpdatesFixtureBase.cs | 14 - .../InheritanceBulkUpdatesFixtureBase.cs | 4 +- .../NorthwindBulkUpdatesFixture.cs | 5 +- .../AssociationsQueryFixtureBase.cs | 16 +- .../ComplexNavigationsQueryFixtureBase.cs | 11 +- ...exNavigationsSharedTypeQueryFixtureBase.cs | 4 +- .../Query/ComplexTypeQueryFixtureBase.cs | 11 +- .../Query/CompositeKeysQueryFixtureBase.cs | 11 +- .../Query/Ef6GroupByTestBase.cs | 11 +- .../Query/FunkyDataQueryTestBase.cs | 10 +- .../Query/GearsOfWarQueryFixtureBase.cs | 11 +- .../Query/IFilteredQueryFixtureBase.cs | 9 - .../Query/IQueryFixtureBase.cs | 26 +- .../InheritanceQueryFixtureBase.cs | 13 +- ...nheritanceRelationshipsQueryFixtureBase.cs | 12 +- .../Query/JsonQueryFixtureBase.cs | 18 +- .../Query/ManyToManyFieldsQueryFixtureBase.cs | 11 +- .../Query/ManyToManyQueryFixtureBase.cs | 11 +- ...SharedPrimitiveCollectionsQueryTestBase.cs | 362 ----- .../Query/NorthwindQueryFixtureBase.cs | 13 +- .../Query/OwnedQueryTestBase.cs | 11 +- .../PrimitiveCollectionsQueryTestBase.cs | 214 ++- .../Query/QueryFixtureBase.cs | 69 + .../Query/QueryTestBase.cs | 125 +- .../Query/SpatialQueryFixtureBase.cs | 11 +- .../BasicTypesQueryFixtureBase.cs | 11 +- .../TestUtilities/BulkUpdatesAsserter.cs | 3 +- .../TestUtilities/QueryAsserter.cs | 2 +- .../Types/TypeEntity.cs | 2 + .../Types/TypeFixtureBase.cs | 6 +- .../Types/TypeTestBase.cs | 15 +- .../BatchingTest.cs | 4 +- ...dPrimitiveCollectionsQuerySqlServerTest.cs | 1210 ----------------- ...imitiveCollectionsQueryOldSqlServerTest.cs | 281 ++++ ...imitiveCollectionsQuerySqlServer160Test.cs | 348 +++++ ...veCollectionsQuerySqlServerJsonTypeTest.cs | 348 +++++ .../PrimitiveCollectionsQuerySqlServerTest.cs | 887 ++++++++++++ .../SqlServerGeographyCollectionTypeTest.cs | 5 + .../SqlServerGeographyLineStringTypeTest.cs | 5 + ...lServerGeographyMultiLineStringTypeTest.cs | 5 + .../SqlServerGeographyMultiPointTypeTest.cs | 5 + .../SqlServerGeographyMultiPolygonTypeTest.cs | 5 + .../SqlServerGeographyPointTypeTest.cs | 5 + .../SqlServerGeographyPolygonTypeTest.cs | 5 + .../SqlServerGeometryCollectionTypeTest.cs | 5 + .../SqlServerGeometryLineStringTypeTest.cs | 5 + ...qlServerGeometryMultiLineStringTypeTest.cs | 5 + .../SqlServerGeometryMultiPointTypeTest.cs | 5 + .../SqlServerGeometryMultiPolygonTypeTest.cs | 5 + .../SqlServerGeometryPointTypeTest.cs | 5 + .../SqlServerGeometryPolygonTypeTest.cs | 5 + .../Miscellaneous/SqlServerBoolTypeTest.cs | 21 +- .../SqlServerByteArrayTypeTest.cs | 8 +- .../Miscellaneous/SqlServerGuidTypeTest.cs | 21 +- .../Miscellaneous/SqlServerStringTypeTest.cs | 21 +- .../Types/Numeric/SqlServerByteTypeTest.cs | 21 +- .../Types/Numeric/SqlServerDecimalTypeTest.cs | 21 +- .../Types/Numeric/SqlServerDoubleTypeTest.cs | 21 +- .../Types/Numeric/SqlServerFloatTypeTest.cs | 21 +- .../Types/Numeric/SqlServerIntTypeTest.cs | 21 +- .../Types/Numeric/SqlServerLongTypeTest.cs | 21 +- .../Types/Numeric/SqlServerShortTypeTest.cs | 21 +- .../Types/SqlServerSpatialTypeTestBase.cs | 16 +- .../Temporal/SqlServerDateOnlyTypeTest.cs | 21 +- .../Temporal/SqlServerDateTime2TypeTest.cs | 21 +- .../SqlServerDateTimeOffsetTypeTest.cs | 21 +- .../Temporal/SqlServerDateTimeTypeTest.cs | 21 +- .../Temporal/SqlServerTimeOnlyTypeTest.cs | 21 +- .../Temporal/SqlServerTimeSpanTypeTest.cs | 21 +- ...aredPrimitiveCollectionsQuerySqliteTest.cs | 576 -------- .../PrimitiveCollectionsQuerySqliteTest.cs | 299 ++++ .../Types/SqliteMiscellaneousTypeTest.cs | 4 + .../Types/SqliteTemporalTypeTest.cs | 4 + 88 files changed, 3518 insertions(+), 3149 deletions(-) delete mode 100644 test/EFCore.Cosmos.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryCosmosTest.cs delete mode 100644 test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs delete mode 100644 test/EFCore.Specification.Tests/BulkUpdates/IBulkUpdatesFixtureBase.cs delete mode 100644 test/EFCore.Specification.Tests/Query/IFilteredQueryFixtureBase.cs delete mode 100644 test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs create mode 100644 test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs delete mode 100644 test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs delete mode 100644 test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryCosmosTest.cs deleted file mode 100644 index 8532978a832..00000000000 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NonSharedPrimitiveCollectionsQueryCosmosTest.cs +++ /dev/null @@ -1,395 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.Cosmos.Internal; - -namespace Microsoft.EntityFrameworkCore.Query; - -public class NonSharedPrimitiveCollectionsQueryCosmosTest(NonSharedFixture fixture) : NonSharedPrimitiveCollectionsQueryTestBase(fixture) -{ - #region Support for specific element types - - public override async Task Array_of_string() - { - await base.Array_of_string(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "a")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_int() - { - await base.Array_of_int(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_long() - { - await base.Array_of_long(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_short() - { - await base.Array_of_short(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - // byte[] gets mapped to base64, which isn't queryable as a regular primitive collection. - [ConditionalFact] - public override Task Array_of_byte() - => AssertTranslationFailed(() => TestArray((byte)1, (byte)2)); - - public override async Task Array_of_double() - { - await base.Array_of_double(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1.0)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_float() - { - await base.Array_of_float(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1.0)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_decimal() - { - await base.Array_of_decimal(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = 1.0)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime() - { - await base.Array_of_DateTime(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "2023-01-01T12:30:00")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime_with_milliseconds() - { - await base.Array_of_DateTime_with_milliseconds(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "2023-01-01T12:30:00.123")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime_with_microseconds() - { - await base.Array_of_DateTime_with_microseconds(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "2023-01-01T12:30:00.123456")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_DateOnly() - { - await base.Array_of_DateOnly(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "2023-01-01")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_TimeOnly() - { - await base.Array_of_TimeOnly(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "12:30:00")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_milliseconds() - { - await base.Array_of_TimeOnly_with_milliseconds(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "12:30:00.123")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_microseconds() - { - await base.Array_of_TimeOnly_with_microseconds(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "12:30:00.123456")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_DateTimeOffset() - { - await base.Array_of_DateTimeOffset(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = "2023-01-01T12:30:00+02:00")) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_bool() - { - await base.Array_of_bool(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM s IN c["SomeArray"] - WHERE (s = true)) = 2) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Array_of_Guid() - { - Assert.Equal( - CosmosStrings.ElementWithValueConverter("Guid[]", "TestEntity", "SomeArray", "Guid"), - (await Assert.ThrowsAsync(() => base.Array_of_Guid())).Message); - - AssertSql(); - } - - public override async Task Array_of_byte_array() - { - // TODO: primitive collection over value-converted element, #34153 - Assert.Equal( - CosmosStrings.ElementWithValueConverter("byte[][]", "TestEntity", "SomeArray", "byte[]"), - (await Assert.ThrowsAsync(() => base.Array_of_byte_array())).Message); - - AssertSql(); - } - - public override async Task Array_of_enum() - { - Assert.Equal( - CosmosStrings.ElementWithValueConverter("MyEnum[]", "TestEntity", "SomeArray", "MyEnum"), - (await Assert.ThrowsAsync(() => base.Array_of_enum())).Message); - - AssertSql(); - } - - [ConditionalFact] - public override Task Multidimensional_array_is_not_supported() - => base.Multidimensional_array_is_not_supported(); - - #endregion Support for specific element types - - public override async Task Column_with_custom_converter() - { - await base.Column_with_custom_converter(); - - AssertSql( - """ -@ints='1,2,3' - -SELECT VALUE c -FROM root c -WHERE (c["Ints"] = @ints) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Parameter_with_inferred_value_converter() - { - await base.Parameter_with_inferred_value_converter(); - - AssertSql(); - } - - public override async Task Constant_with_inferred_value_converter() - { - // TODO: advanced type mapping inference for inline scalar collection, #34026 - await AssertTranslationFailed(() => base.Constant_with_inferred_value_converter()); - - AssertSql(); - } - - public override async Task Inline_collection_in_query_filter() - { - await base.Inline_collection_in_query_filter(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (( - SELECT VALUE COUNT(1) - FROM a IN (SELECT VALUE [1, 2, 3]) - WHERE (a > c["Id"])) = 1) -OFFSET 0 LIMIT 2 -"""); - } - - public override async Task Project_collection_from_entity_type_with_owned() - { - await base.Project_collection_from_entity_type_with_owned(); - - AssertSql( - """ -SELECT VALUE c["Ints"] -FROM root c -WHERE (c["$type"] = "TestEntityWithOwned") -"""); - } - - public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() - { - await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE ((c["$type"] = "SubType") AND (ARRAY_LENGTH(c["Ints"]) > 0)) -"""); - } - - [ConditionalFact] - public virtual void Check_all_tests_overridden() - => TestHelpers.AssertAllMethodsOverridden(GetType()); - - protected override ITestStoreFactory TestStoreFactory - => CosmosTestStoreFactory.Instance; - - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(w => w.Ignore(CosmosEventId.NoPartitionKeyDefined)); - - protected TestSqlLoggerFactory TestSqlLoggerFactory - => (TestSqlLoggerFactory)ListLoggerFactory; - - protected void ClearLog() - => TestSqlLoggerFactory.Clear(); - - protected void AssertSql(params string[] expected) - => TestSqlLoggerFactory.AssertBaseline(expected); -} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index 4593d183f5a..5881b3dd2f4 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -498,6 +498,22 @@ FROM p IN (SELECT VALUE @p) """); } + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (( + SELECT VALUE COUNT(1) + FROM a IN (SELECT VALUE [1, 2, 3]) + WHERE (a > c["Id"])) = 1) +OFFSET 0 LIMIT 2 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -727,6 +743,56 @@ WHERE ARRAY_CONTAINS(@nullableInts, c["NullableInt"]) """); } + public override async Task Parameter_collection_of_structs_Contains_struct() + { + // Requires collections of converted elements + await Assert.ThrowsAsync(base.Parameter_collection_of_structs_Contains_struct); + + AssertSql(); + } + + public override async Task Parameter_collection_of_structs_Contains_nullable_struct() + { + // Requires collections of converted elements + await Assert.ThrowsAsync(base.Parameter_collection_of_structs_Contains_nullable_struct); + + AssertSql(); + } + + public override async Task Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer() + { + // Requires collections of converted elements + await Assert.ThrowsAsync( + base.Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer); + + AssertSql(); + } + + public override async Task Parameter_collection_of_nullable_structs_Contains_struct() + { + // Requires collections of converted elements + await Assert.ThrowsAsync(base.Parameter_collection_of_nullable_structs_Contains_struct); + + AssertSql(); + } + + public override async Task Parameter_collection_of_nullable_structs_Contains_nullable_struct() + { + // Requires collections of converted elements + await Assert.ThrowsAsync(base.Parameter_collection_of_nullable_structs_Contains_nullable_struct); + + AssertSql(); + } + + public override async Task Parameter_collection_of_nullable_structs_Contains_nullable_struct_with_nullable_comparer() + { + // Requires collections of converted elements + await Assert.ThrowsAsync( + base.Parameter_collection_of_nullable_structs_Contains_nullable_struct_with_nullable_comparer); + + AssertSql(); + } + public override async Task Parameter_collection_of_strings_Contains_string() { await base.Parameter_collection_of_strings_Contains_string(); @@ -1101,6 +1167,76 @@ WHERE ARRAY_CONTAINS(c["Bools"], true) """); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' + +SELECT VALUE c +FROM root c +WHERE (c["Ints"] = @ints) +OFFSET 0 LIMIT 2 +"""); + } + + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(); + } + + public override async Task Constant_with_inferred_value_converter() + { + // TODO: advanced type mapping inference for inline scalar collection, #34026 + await AssertTranslationFailed(() => base.Constant_with_inferred_value_converter()); + + AssertSql(); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + + public override async Task Contains_on_Enumerable() + { + await base.Contains_on_Enumerable(); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["Int"] IN (10, 999) +"""); + } + + public override async Task Contains_on_MemoryExtensions() + { + await base.Contains_on_MemoryExtensions(); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["Int"] IN (10, 999) +"""); + } + + public override async Task Contains_with_MemoryExtensions_with_null_comparer() + { + await base.Contains_with_MemoryExtensions_with_null_comparer(); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE c["Int"] IN (10, 999) +"""); + } + public override async Task Column_collection_Count_method() { await base.Column_collection_Count_method(); @@ -2087,6 +2223,30 @@ WHERE ARRAY_CONTAINS(@strings, (ARRAY_CONTAINS(@ints, c["Int"]) ? "one" : "two") """); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT VALUE c["Ints"] +FROM root c +WHERE (c["$type"] = "TestEntityWithOwned") +"""); + } + + public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE ((c["$type"] = "SubType") AND (ARRAY_LENGTH(c["Ints"]) > 0)) +"""); + } + public override async Task Values_of_enum_casted_to_underlying_value() { await base.Values_of_enum_casted_to_underlying_value(); @@ -2136,92 +2296,6 @@ FROM root c #endregion Cosmos-specific tests - public override async Task Parameter_collection_of_structs_Contains_struct() - { - // Requires collections of converted elements - await Assert.ThrowsAsync(base.Parameter_collection_of_structs_Contains_struct); - - AssertSql(); - } - - public override async Task Parameter_collection_of_structs_Contains_nullable_struct() - { - // Requires collections of converted elements - await Assert.ThrowsAsync(base.Parameter_collection_of_structs_Contains_nullable_struct); - - AssertSql(); - } - - public override async Task Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer() - { - // Requires collections of converted elements - await Assert.ThrowsAsync( - base.Parameter_collection_of_structs_Contains_nullable_struct_with_nullable_comparer); - - AssertSql(); - } - - public override async Task Parameter_collection_of_nullable_structs_Contains_struct() - { - // Requires collections of converted elements - await Assert.ThrowsAsync(base.Parameter_collection_of_nullable_structs_Contains_struct); - - AssertSql(); - } - - public override async Task Parameter_collection_of_nullable_structs_Contains_nullable_struct() - { - // Requires collections of converted elements - await Assert.ThrowsAsync(base.Parameter_collection_of_nullable_structs_Contains_nullable_struct); - - AssertSql(); - } - - public override async Task Parameter_collection_of_nullable_structs_Contains_nullable_struct_with_nullable_comparer() - { - // Requires collections of converted elements - await Assert.ThrowsAsync( - base.Parameter_collection_of_nullable_structs_Contains_nullable_struct_with_nullable_comparer); - - AssertSql(); - } - - public override async Task Contains_on_Enumerable() - { - await base.Contains_on_Enumerable(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE c["Int"] IN (10, 999) -"""); - } - - public override async Task Contains_on_MemoryExtensions() - { - await base.Contains_on_MemoryExtensions(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE c["Int"] IN (10, 999) -"""); - } - - public override async Task Contains_with_MemoryExtensions_with_null_comparer() - { - await base.Contains_with_MemoryExtensions_with_null_comparer(); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE c["Int"] IN (10, 999) -"""); - } - [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs index ba6c21a9d98..e451dfb03d7 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/ReadItemPartitionKeyQueryFixtureBase.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Linq; - namespace Microsoft.EntityFrameworkCore.Query; -public class ReadItemPartitionKeyQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public class ReadItemPartitionKeyQueryFixtureBase : QueryFixtureBase { protected PartitionKeyData? ExpectedData { get; set; } @@ -85,9 +83,6 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; - public Func GetContextCreator() - => () => CreateContext(); - protected override Task SeedAsync(DbContext context) { var data = (PartitionKeyData)GetExpectedData(); @@ -106,10 +101,10 @@ protected override Task SeedAsync(DbContext context) return context.SaveChangesAsync(); } - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => ExpectedData ??= new PartitionKeyData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(HierarchicalPartitionKeyEntity), e => ((HierarchicalPartitionKeyEntity?)e)?.Id }, { typeof(OnlyHierarchicalPartitionKeyEntity), e => ((OnlyHierarchicalPartitionKeyEntity?)e)?.Payload }, @@ -122,7 +117,7 @@ public virtual ISetSource GetExpectedData() { typeof(SharedContainerEntity3), e => ((SharedContainerEntity3?)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(HierarchicalPartitionKeyEntity), (e, a) => diff --git a/test/EFCore.Cosmos.FunctionalTests/Types/CosmosMiscellaneousTypeTest.cs b/test/EFCore.Cosmos.FunctionalTests/Types/CosmosMiscellaneousTypeTest.cs index 6cfad22f8d8..918cae035d4 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Types/CosmosMiscellaneousTypeTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Types/CosmosMiscellaneousTypeTest.cs @@ -30,18 +30,32 @@ public class StringTypeFixture : CosmosTypeFixtureBase public class CosmosGuidTypeTest(CosmosGuidTypeTest.GuidTypeFixture fixture) : TypeTestBase(fixture) { + // Cosmos doesn't support value converters on primitive collection elements (Guid requires one) + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public class GuidTypeFixture : CosmosTypeFixtureBase { public override Guid Value { get; } = new("8f7331d6-cde9-44fb-8611-81fff686f280"); public override Guid OtherValue { get; } = new("ae192c36-9004-49b2-b785-8be10d169627"); protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + modelBuilder.Entity>().Ignore(e => e.ArrayValue); + } } } public class CosmosByteArrayTypeTest(CosmosByteArrayTypeTest.ByteArrayTypeFixture fixture) : TypeTestBase(fixture) { + // Cosmos doesn't support value converters on primitive collection elements (byte[] requires one) + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public class ByteArrayTypeFixture : CosmosTypeFixtureBase { public override byte[] Value { get; } = [1, 2, 3]; @@ -50,5 +64,12 @@ public class ByteArrayTypeFixture : CosmosTypeFixtureBase protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; public override Func Comparer { get; } = (a, b) => a.SequenceEqual(b); + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Entity>().Ignore(e => e.ArrayValue); + } } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Types/CosmosNumericTypeTest.cs b/test/EFCore.Cosmos.FunctionalTests/Types/CosmosNumericTypeTest.cs index 2d680199118..5211f1fe934 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Types/CosmosNumericTypeTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Types/CosmosNumericTypeTest.cs @@ -6,6 +6,10 @@ namespace Microsoft.EntityFrameworkCore.Types.Numeric; public class CosmosByteTypeTest(CosmosByteTypeTest.ByteTypeFixture fixture) : TypeTestBase(fixture) { + // Cosmos can't translate byte.Equals() in primitive collection queries + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public class ByteTypeFixture : CosmosTypeFixtureBase { public override byte Value { get; } = byte.MinValue; diff --git a/test/EFCore.Relational.Specification.Tests/Query/Associations/RelationalAssociationsTests.cs b/test/EFCore.Relational.Specification.Tests/Query/Associations/RelationalAssociationsTests.cs index 035d091317e..a438ee4f68f 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/Associations/RelationalAssociationsTests.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/Associations/RelationalAssociationsTests.cs @@ -6,9 +6,9 @@ namespace Microsoft.EntityFrameworkCore.Query.Associations; public class RelationalAssociationsTests { internal static async Task FromSql_on_root(QueryTestBase queryTestBase, TFixture fixture) - where TFixture : SharedStoreFixtureBase, IQueryFixtureBase, new() + where TFixture : class, IQueryFixtureBase, new() { - using var context = fixture.CreateContext(); + using var context = fixture.GetContextCreator()(); var tableName = context.Model.FindEntityType(typeof(RootEntity))?.GetTableName() ?? throw new UnreachableException("Couldn't find relational table name for RootEntity"); var sqlGenerationHelper = context.GetService(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs deleted file mode 100644 index 4222fd31e2f..00000000000 --- a/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs +++ /dev/null @@ -1,255 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Query; - -#nullable disable - -public abstract class NonSharedPrimitiveCollectionsQueryRelationalTestBase(NonSharedFixture fixture) - : NonSharedPrimitiveCollectionsQueryTestBase(fixture) -{ - // On relational databases, byte[] gets mapped to a special binary data type, which isn't queryable as a regular primitive collection. - [ConditionalFact] - public override Task Array_of_byte() - => AssertTranslationFailed(() => TestArray((byte)1, (byte)2)); - - protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode( - DbContextOptionsBuilder optionsBuilder, - ParameterTranslationMode parameterizedCollectionMode); - -#pragma warning disable EF8001 // Owned JSON entities are obsolete - [ConditionalFact] - public virtual async Task Column_collection_inside_json_owned_entity() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity().OwnsOne(t => t.Owned, b => b.ToJson()), - seed: context => - { - context.AddRange( - new TestOwner { Owned = new TestOwned { Strings = ["foo", "bar"] } }, - new TestOwner { Owned = new TestOwned { Strings = ["baz"] } }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var result = await context.Set().SingleAsync(o => o.Owned.Strings.Count() == 2); - Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); - - result = await context.Set().SingleAsync(o => o.Owned.Strings[1] == "bar"); - Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); - } -#pragma warning restore EF8001 - - protected static IEnumerable ParameterTranslationModeValues() - => Enum.GetValues().Select(x => [x]); - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 100 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Constant(ids).Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 100 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Constant(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Parameter(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) - .ToListAsync(); - Assert.Equivalent(new[] { 100 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Parameter(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( - ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.MultipleParameters(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) - .ToListAsync(); - Assert.Equivalent(new[] { 100 }, result); - } - - [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] - public virtual async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, mode), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.MultipleParameters(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_parameter_bucketization() - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterTranslationMode.MultipleParameters), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; - var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(c => c.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - protected class TestOwner - { - public int Id { get; set; } - public TestOwned Owned { get; set; } - } - - [Owned] - protected class TestOwned - { - public string[] Strings { get; set; } - } - - protected TestSqlLoggerFactory TestSqlLoggerFactory - => (TestSqlLoggerFactory)ListLoggerFactory; - - protected void ClearLog() - => TestSqlLoggerFactory.Clear(); - - protected void AssertSql(params string[] expected) - => TestSqlLoggerFactory.AssertBaseline(expected); -} diff --git a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs index ae81c844894..9308a9a1c6e 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NullSemanticsQueryFixtureBase.cs @@ -8,21 +8,19 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class NullSemanticsQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase, ITestSqlLoggerFactory +public abstract class NullSemanticsQueryFixtureBase : QueryFixtureBase, ITestSqlLoggerFactory { - public Func GetContextCreator() - => () => CreateContext(); - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => NullSemanticsData.Instance; - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(NullSemanticsEntity1), e => ((NullSemanticsEntity1)e)?.Id }, { typeof(NullSemanticsEntity2), e => ((NullSemanticsEntity2)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(NullSemanticsEntity1), (e, a) => diff --git a/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs index cf83c519702..60338e58dd2 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OptionalDependentQueryFixtureBase.cs @@ -7,25 +7,21 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class OptionalDependentQueryFixtureBase : SharedStoreFixtureBase, - IQueryFixtureBase, +public abstract class OptionalDependentQueryFixtureBase : QueryFixtureBase, ITestSqlLoggerFactory { private OptionalDependentData _expectedData; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new OptionalDependentData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(OptionalDependentEntityAllOptional), e => ((OptionalDependentEntityAllOptional)e)?.Id }, { typeof(OptionalDependentEntitySomeRequired), e => ((OptionalDependentEntitySomeRequired)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(OptionalDependentEntityAllOptional), (e, a) => diff --git a/test/EFCore.Relational.Specification.Tests/Query/PrimitiveCollectionsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/PrimitiveCollectionsQueryRelationalTestBase.cs index cfe5406116c..a83e5e99724 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/PrimitiveCollectionsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/PrimitiveCollectionsQueryRelationalTestBase.cs @@ -5,9 +5,13 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public class PrimitiveCollectionsQueryRelationalTestBase(TFixture fixture) : PrimitiveCollectionsQueryTestBase(fixture) +public abstract class PrimitiveCollectionsQueryRelationalTestBase(TFixture fixture) : PrimitiveCollectionsQueryTestBase(fixture) where TFixture : PrimitiveCollectionsQueryTestBase.PrimitiveCollectionsQueryFixtureBase, new() { + protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode); + [ConditionalFact] public override async Task Inline_collection_Count_with_zero_values() { @@ -16,12 +20,232 @@ public override async Task Inline_collection_Count_with_zero_values() Assert.Equal(RelationalStrings.EmptyCollectionNotSupportedAsInlineQueryRoot, exception.Message); } + protected static IEnumerable ParameterTranslationModeValues() + => Enum.GetValues().Select(x => [x]); + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Constant(ids).Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Constant(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Parameter(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) + .ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.Parameter(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ids = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.MultipleParameters(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) + .ToListAsync(); + Assert.Equivalent(new[] { 100 }, result); + } + + [ConditionalTheory, MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, mode), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 2, 999 }; + var result = await context.Set().Where(c => EF.MultipleParameters(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + + [ConditionalFact] + public virtual async Task Parameter_collection_Contains_parameter_bucketization() + { + var contextFactory = await InitializeNonSharedTest( + onConfiguring: b => SetParameterizedCollectionMode(b, ParameterTranslationMode.MultipleParameters), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }, + new TestEntity { Id = 100 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 2, 999, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; + var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(c => c.Id).ToListAsync(); + Assert.Equivalent(new[] { 2 }, result); + } + +#pragma warning disable EF8001 // Owned JSON entities are obsolete + [ConditionalFact] + public virtual async Task Column_collection_inside_json_owned_entity() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity().OwnsOne(t => t.Owned, b => b.ToJson()), + seed: context => + { + context.AddRange( + new TestOwner { Owned = new TestOwned { Strings = ["foo", "bar"] } }, + new TestOwner { Owned = new TestOwned { Strings = ["baz"] } }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var result = await context.Set().SingleAsync(o => o.Owned.Strings.Count() == 2); + Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); + + result = await context.Set().SingleAsync(o => o.Owned.Strings[1] == "bar"); + Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); + } +#pragma warning restore EF8001 + public override Task Column_collection_Concat_parameter_collection_equality_inline_collection() => AssertTranslationFailed(base.Column_collection_Concat_parameter_collection_equality_inline_collection); public override Task Column_collection_equality_inline_collection_with_parameters() => AssertTranslationFailed(base.Column_collection_equality_inline_collection_with_parameters); + // TODO: Requires converting the results of a subquery (relational rowset) to a primitive collection for comparison, + // not yet supported (#33792) + public override async Task Column_collection_Where_equality_inline_collection() + => await AssertTranslationFailed(base.Column_collection_Where_equality_inline_collection); + [ConditionalFact] public override void Parameter_collection_in_subquery_and_Convert_as_compiled_query() { @@ -50,8 +274,15 @@ public override async Task Project_inline_collection_with_Concat() Assert.Equal(RelationalStrings.InsufficientInformationToIdentifyElementOfCollectionJoin, message); } - // TODO: Requires converting the results of a subquery (relational rowset) to a primitive collection for comparison, - // not yet supported (#33792) - public override async Task Column_collection_Where_equality_inline_collection() - => await AssertTranslationFailed(base.Column_collection_Where_equality_inline_collection); + protected class TestOwner + { + public int Id { get; set; } + public TestOwned Owned { get; set; } = null!; + } + + [Owned] + protected class TestOwned + { + public string[] Strings { get; set; } = null!; + } } diff --git a/test/EFCore.Relational.Specification.Tests/Query/Translations/JsonTranslationsRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/Translations/JsonTranslationsRelationalTestBase.cs index e937ebd5e79..6f35434428e 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/Translations/JsonTranslationsRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/Translations/JsonTranslationsRelationalTestBase.cs @@ -78,7 +78,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) // The translation tests usually use BasicTypesQueryFixtureBase, which manages a single database with all the data needed for the tests. // However, here in the JSON translation tests we use a separate fixture and database, since not all providers necessary implement full // JSON support, and we don't want to make life difficult for them with the basic translation tests. - public abstract class JsonTranslationsQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase, ITestSqlLoggerFactory + public abstract class JsonTranslationsQueryFixtureBase : QueryFixtureBase, ITestSqlLoggerFactory { private JsonTranslationsData? _expectedData; @@ -110,15 +110,15 @@ await context.Database.ExecuteSqlRawAsync( protected abstract string RemoveJsonProperty(string column, string property); - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new JsonTranslationsData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(JsonTranslationsEntity), e => ((JsonTranslationsEntity?)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(JsonTranslationsEntity), (e, a) => @@ -142,7 +142,7 @@ public virtual ISetSource GetExpectedData() } }.ToDictionary(e => e.Key, e => (object)e.Value); - public Func GetContextCreator() + public override Func GetContextCreator() => CreateContext; public TestSqlLoggerFactory TestSqlLoggerFactory diff --git a/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs b/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs index 641018ea791..b3a8c398ba3 100644 --- a/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/RelationalComplianceTestBase.cs @@ -17,10 +17,8 @@ public virtual void All_query_test_fixtures_must_implement_ITestSqlLoggerFactory var queryFixturesWithoutTestSqlLogger = TargetAssembly .GetTypes() .Where(x => x.BaseType != typeof(object) && (x.IsPublic || x.IsNestedPublic)) - .Select(x => new { Type = x, Interfaces = x.GetInterfaces().ToList() }) - .Where(x => x.Interfaces.Contains(typeof(IQueryFixtureBase))) - .Where(x => !x.Interfaces.Contains(typeof(ITestSqlLoggerFactory))) - .Select(x => x.Type) + .Where(x => typeof(IQueryFixtureBase).IsAssignableFrom(x)) + .Where(x => !x.GetInterfaces().Contains(typeof(ITestSqlLoggerFactory))) .ToList(); Assert.False( diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs index 4c8ee94c8bf..a9a435cd3e1 100644 --- a/test/EFCore.Relational.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs +++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.BulkUpdates; +using Microsoft.EntityFrameworkCore.Query; namespace Microsoft.EntityFrameworkCore.TestUtilities; -public class BulkUpdatesAsserter(IBulkUpdatesFixtureBase queryFixture, Func rewriteServerQueryExpression) +public class BulkUpdatesAsserter(IQueryFixtureBase queryFixture, Func rewriteServerQueryExpression) { private readonly Func _contextCreator = queryFixture.GetContextCreator(); private readonly Action _useTransaction = queryFixture.GetUseTransaction(); diff --git a/test/EFCore.Relational.Specification.Tests/Types/RelationalTypeFixtureBase.cs b/test/EFCore.Relational.Specification.Tests/Types/RelationalTypeFixtureBase.cs index 5396b5bfda1..fdc2ae139b1 100644 --- a/test/EFCore.Relational.Specification.Tests/Types/RelationalTypeFixtureBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Types/RelationalTypeFixtureBase.cs @@ -16,6 +16,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b.ToTable(nameof(TypeEntity<>)); b.Property(e => e.Value).HasColumnType(StoreType); b.Property(e => e.OtherValue).HasColumnType(StoreType); + b.PrimitiveCollection(e => e.ArrayValue).ElementType(e => e.HasStoreType(StoreType)); }); modelBuilder.Entity>(b => diff --git a/test/EFCore.Specification.Tests/BulkUpdates/BulkUpdatesTestBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/BulkUpdatesTestBase.cs index b89b0dc9754..3ba8400215e 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/BulkUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/BulkUpdatesTestBase.cs @@ -6,7 +6,7 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable public abstract class BulkUpdatesTestBase : IClassFixture - where TFixture : class, IBulkUpdatesFixtureBase, new() + where TFixture : class, IQueryFixtureBase, new() { protected BulkUpdatesTestBase(TFixture fixture) { diff --git a/test/EFCore.Specification.Tests/BulkUpdates/IBulkUpdatesFixtureBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/IBulkUpdatesFixtureBase.cs deleted file mode 100644 index 8b7415d46d6..00000000000 --- a/test/EFCore.Specification.Tests/BulkUpdates/IBulkUpdatesFixtureBase.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.BulkUpdates; - -#nullable disable - -public interface IBulkUpdatesFixtureBase : IQueryFixtureBase -{ - Action GetUseTransaction() - => UseTransaction; - - void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction); -} diff --git a/test/EFCore.Specification.Tests/BulkUpdates/Inheritance/InheritanceBulkUpdatesFixtureBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/Inheritance/InheritanceBulkUpdatesFixtureBase.cs index 794a6a239d2..df9400c8fff 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/Inheritance/InheritanceBulkUpdatesFixtureBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/Inheritance/InheritanceBulkUpdatesFixtureBase.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates.Inheritance; #nullable disable -public abstract class InheritanceBulkUpdatesFixtureBase : InheritanceQueryFixtureBase, IBulkUpdatesFixtureBase +public abstract class InheritanceBulkUpdatesFixtureBase : InheritanceQueryFixtureBase { public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder).ConfigureWarnings(w => w.Log(CoreEventId.FirstWithoutOrderByAndFilterWarning) @@ -16,5 +16,5 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build CoreEventId.MappedPropertyIgnoredWarning, CoreEventId.MappedNavigationIgnoredWarning)); - public abstract void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction); + public abstract override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction); } diff --git a/test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesFixture.cs b/test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesFixture.cs index 238f0ec5917..0d364ea45d6 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesFixture.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesFixture.cs @@ -5,12 +5,11 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; #nullable disable -public abstract class NorthwindBulkUpdatesFixture : NorthwindQueryFixtureBase, - IBulkUpdatesFixtureBase +public abstract class NorthwindBulkUpdatesFixture : NorthwindQueryFixtureBase where TModelCustomizer : ITestModelCustomizer, new() { protected override string StoreName => "BulkUpdatesNorthwind"; - public abstract void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction); + public abstract override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction); } diff --git a/test/EFCore.Specification.Tests/Query/Associations/AssociationsQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/Associations/AssociationsQueryFixtureBase.cs index 02882b2c306..01965620865 100644 --- a/test/EFCore.Specification.Tests/Query/Associations/AssociationsQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/Associations/AssociationsQueryFixtureBase.cs @@ -1,18 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.BulkUpdates; - namespace Microsoft.EntityFrameworkCore.Query.Associations; -public abstract class AssociationsQueryFixtureBase : SharedStoreFixtureBase, - IQueryFixtureBase, IBulkUpdatesFixtureBase +public abstract class AssociationsQueryFixtureBase : QueryFixtureBase { public virtual bool AreCollectionsOrdered => true; - - public virtual void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) + public override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => throw new NotSupportedException(); public AssociationsData Data { get; private set; } @@ -45,10 +41,10 @@ public AssociationsQueryFixtureBase() }.ToDictionary(e => e.Key, e => e.Value); } - public Func GetContextCreator() + public override Func GetContextCreator() => CreateContext; - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => Data; protected virtual AssociationsData CreateData() @@ -78,7 +74,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .IsRequired(false); } - public virtual IReadOnlyDictionary EntitySorters { get; } = new Dictionary + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary { { typeof(RootEntity), object? (RootEntity e) => ((RootEntity?)e)?.Id }, { typeof(AssociateType), object? (AssociateType e) => ((AssociateType?)e)?.Id }, @@ -92,7 +88,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con { typeof(ValueNestedType?), object? (ValueNestedType? e) => e?.Id } }.ToDictionary(e => e.Key, e => e.Value); - public virtual IReadOnlyDictionary EntityAsserters { get; } + public override IReadOnlyDictionary EntityAsserters { get; } protected virtual void AssertRootEntity(RootEntity e, RootEntity a) { diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryFixtureBase.cs index e2c43dcc323..bfd3a983649 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryFixtureBase.cs @@ -7,15 +7,12 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class ComplexNavigationsQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class ComplexNavigationsQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "ComplexNavigations"; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => ComplexNavigationsDefaultData.Instance; public virtual Dictionary<(Type, string), Func> GetShadowPropertyMappings() @@ -184,7 +181,7 @@ public virtual ISetSource GetExpectedData() }; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(Level1), e => ((Level1)e)?.Id }, { typeof(Level2), e => ((Level2)e)?.Id }, @@ -198,7 +195,7 @@ public virtual ISetSource GetExpectedData() { typeof(InheritanceLeaf2), e => ((InheritanceLeaf2)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(Level1), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryFixtureBase.cs index 07a1acefe6f..9c0de2503ef 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsSharedTypeQueryFixtureBase.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class ComplexNavigationsSharedTypeQueryFixtureBase : ComplexNavigationsQueryFixtureBase, IQueryFixtureBase +public abstract class ComplexNavigationsSharedTypeQueryFixtureBase : ComplexNavigationsQueryFixtureBase { protected override string StoreName => "ComplexNavigationsOwned"; @@ -16,7 +16,7 @@ protected override string StoreName public override ISetSource GetExpectedData() => ComplexNavigationsWeakData.Instance; - Func IQueryFixtureBase.GetSetSourceCreator() + public override Func GetSetSourceCreator() => context => new ComplexNavigationsWeakSetExtractor(context); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) diff --git a/test/EFCore.Specification.Tests/Query/ComplexTypeQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ComplexTypeQueryFixtureBase.cs index c597aeadbc6..45fd758ea7b 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexTypeQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexTypeQueryFixtureBase.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.Query; -public abstract class ComplexTypeQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class ComplexTypeQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "ComplexTypeQueryTest"; @@ -59,13 +59,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con }); } - public Func GetContextCreator() - => () => CreateContext(); - - public ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new ComplexTypeData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary { { typeof(Customer), (Func)(e => e.Id) }, { typeof(CustomerGroup), (Func)(e => e.Id) }, @@ -79,7 +76,7 @@ public ISetSource GetExpectedData() { typeof(CountryStruct), (Func)(e => e.Code) } }.ToDictionary(e => e.Key, e => e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary { { typeof(Customer), (Customer e, Customer a) => diff --git a/test/EFCore.Specification.Tests/Query/CompositeKeysQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/CompositeKeysQueryFixtureBase.cs index 72f7945a077..04b721bc956 100644 --- a/test/EFCore.Specification.Tests/Query/CompositeKeysQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/CompositeKeysQueryFixtureBase.cs @@ -7,15 +7,12 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class CompositeKeysQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class CompositeKeysQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "CompositeKeys"; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => CompositeKeysDefaultData.Instance; public virtual Dictionary<(Type, string), Func> GetShadowPropertyMappings() @@ -198,7 +195,7 @@ public virtual ISetSource GetExpectedData() }; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(CompositeOne), e => (((CompositeOne)e)?.Id1, ((CompositeOne)e)?.Id2) }, { typeof(CompositeTwo), e => (((CompositeTwo)e)?.Id1, ((CompositeTwo)e)?.Id2) }, @@ -206,7 +203,7 @@ public virtual ISetSource GetExpectedData() { typeof(CompositeFour), e => (((CompositeFour)e)?.Id1, ((CompositeFour)e)?.Id2) }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(CompositeOne), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs b/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs index f5f06a142fb..38d2319e797 100644 --- a/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/Ef6GroupByTestBase.cs @@ -675,16 +675,13 @@ protected virtual void ClearLog() { } - public abstract class Ef6GroupByFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase + public abstract class Ef6GroupByFixtureBase : QueryFixtureBase { private ArubaData _expectedData; protected override string StoreName => "Ef6GroupByTest"; - public Func GetContextCreator() - => () => CreateContext(); - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { modelBuilder.Entity(b => @@ -729,10 +726,10 @@ protected override Task SeedAsync(ArubaContext context) return context.SaveChangesAsync(); } - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new ArubaData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(CustomerForLinq), e => ((CustomerForLinq)e)?.Id }, { typeof(OrderForLinq), e => ((OrderForLinq)e)?.Id }, @@ -741,7 +738,7 @@ public virtual ISetSource GetExpectedData() { typeof(Feet), e => ((Feet)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(CustomerForLinq), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs index 521b4e5eafc..f75a51fcc5c 100644 --- a/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/FunkyDataQueryTestBase.cs @@ -538,19 +538,17 @@ protected virtual void ClearLog() { } - public abstract class FunkyDataQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase + public abstract class FunkyDataQueryFixtureBase : QueryFixtureBase { - public Func GetContextCreator() - => () => CreateContext(); - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => FunkyDataData.Instance; - public IReadOnlyDictionary EntitySorters { get; } = + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(FunkyCustomer), e => ((FunkyCustomer)e)?.Id } } .ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(FunkyCustomer), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryFixtureBase.cs index 82878f33daa..a03ad553326 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryFixtureBase.cs @@ -7,15 +7,12 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class GearsOfWarQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class GearsOfWarQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "GearsOfWarQueryTest"; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => GearsOfWarData.Instance; public virtual Dictionary<(Type, string), Func> GetShadowPropertyMappings() @@ -28,7 +25,7 @@ public virtual ISetSource GetExpectedData() }, }; - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(City), e => ((City)e)?.Name }, { typeof(CogTag), e => ((CogTag)e)?.Id }, @@ -45,7 +42,7 @@ public virtual ISetSource GetExpectedData() { typeof(LocustHighCommand), e => ((LocustHighCommand)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(City), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/IFilteredQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/IFilteredQueryFixtureBase.cs deleted file mode 100644 index aee255ad2ca..00000000000 --- a/test/EFCore.Specification.Tests/Query/IFilteredQueryFixtureBase.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Query; - -public interface IFilteredQueryFixtureBase : IQueryFixtureBase -{ - ISetSource GetFilteredExpectedData(DbContext context); -} diff --git a/test/EFCore.Specification.Tests/Query/IQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/IQueryFixtureBase.cs index b440c3387d4..f7791aa2f80 100644 --- a/test/EFCore.Specification.Tests/Query/IQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/IQueryFixtureBase.cs @@ -1,29 +1,21 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.EntityFrameworkCore.Query; public interface IQueryFixtureBase { - Func GetContextCreator(); - - Func GetSetSourceCreator() - => context => new DefaultSetSource(context); + string StoreName { get; } + Func GetContextCreator(); + Func GetSetSourceCreator(); ISetSource GetExpectedData(); - IReadOnlyDictionary EntitySorters { get; } - IReadOnlyDictionary EntityAsserters { get; } - + ISetSource? GetFilteredExpectedData(DbContext context); + Action GetUseTransaction(); + TestStore GetOrCreateNonSharedTestStore(Func createTestStore); + ITestStoreFactory GetTestStoreFactory(); ListLoggerFactory ListLoggerFactory { get; } - - private class DefaultSetSource(DbContext context) : ISetSource - { - private readonly DbContext _context = context; - - public IQueryable Set() - where TEntity : class - => _context.Set(); - } + DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder); } diff --git a/test/EFCore.Specification.Tests/Query/Inheritance/InheritanceQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/Inheritance/InheritanceQueryFixtureBase.cs index 3ec1ef96ec5..49022a1d9f2 100644 --- a/test/EFCore.Specification.Tests/Query/Inheritance/InheritanceQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/Inheritance/InheritanceQueryFixtureBase.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Inheritance; #nullable disable -public abstract class InheritanceQueryFixtureBase : SharedStoreFixtureBase, IFilteredQueryFixtureBase +public abstract class InheritanceQueryFixtureBase : QueryFixtureBase { private readonly Dictionary _expectedDataCache = new(); @@ -35,15 +35,12 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build CoreEventId.MappedPropertyIgnoredWarning, CoreEventId.MappedNavigationIgnoredWarning)); - public Func GetContextCreator() - => CreateContext; - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => UseGeneratedKeys ? InheritanceData.GeneratedKeysInstance : InheritanceData.Instance; - public virtual ISetSource GetFilteredExpectedData(DbContext context) + public override ISetSource GetFilteredExpectedData(DbContext context) { if (_expectedDataCache.TryGetValue(EnableFilters, out var cachedResult)) { @@ -64,7 +61,7 @@ public virtual ISetSource GetFilteredExpectedData(DbContext context) return expectedData; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(Animal), e => ((Animal)e)?.Species }, { typeof(Bird), e => ((Bird)e)?.Species }, @@ -87,7 +84,7 @@ public virtual ISetSource GetFilteredExpectedData(DbContext context) { typeof(NestedComplexType), e => ((NestedComplexType)e)?.UniqueInt }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } + public override IReadOnlyDictionary EntityAsserters { get; } public InheritanceQueryFixtureBase() => EntityAsserters = new Dictionary> diff --git a/test/EFCore.Specification.Tests/Query/InheritanceRelationshipsQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/InheritanceRelationshipsQueryFixtureBase.cs index 34b444ddc7f..d19766a3d2c 100644 --- a/test/EFCore.Specification.Tests/Query/InheritanceRelationshipsQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/InheritanceRelationshipsQueryFixtureBase.cs @@ -7,19 +7,15 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class InheritanceRelationshipsQueryFixtureBase : SharedStoreFixtureBase, - IQueryFixtureBase +public abstract class InheritanceRelationshipsQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "InheritanceRelationships"; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => InheritanceRelationshipsData.Instance; - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(BaseCollectionOnBase), e => ((BaseCollectionOnBase)e)?.Id }, { typeof(DerivedCollectionOnBase), e => ((DerivedCollectionOnBase)e)?.Id }, @@ -44,7 +40,7 @@ public virtual ISetSource GetExpectedData() { typeof(ReferenceOnDerived), e => ((ReferenceOnDerived)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(BaseCollectionOnBase), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs index f1d8009acb1..e3dba32f797 100644 --- a/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/JsonQueryFixtureBase.cs @@ -7,17 +7,14 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class JsonQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class JsonQueryFixtureBase : QueryFixtureBase { private JsonQueryData _expectedData; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new JsonQueryData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(EntityBasic), e => ((EntityBasic)e)?.Id }, { typeof(JsonEntityBasic), e => ((JsonEntityBasic)e)?.Id }, @@ -30,7 +27,7 @@ public virtual ISetSource GetExpectedData() { typeof(JsonEntityAllTypes), e => ((JsonEntityAllTypes)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public virtual IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(EntityBasic), (e, a) => @@ -652,13 +649,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con protected override string StoreName => "JsonQueryTest"; - public override JsonQueryContext CreateContext() - { - var context = base.CreateContext(); - - return context; - } - protected override async Task SeedAsync(JsonQueryContext context) => await JsonQueryContext.SeedAsync(context); } diff --git a/test/EFCore.Specification.Tests/Query/ManyToManyFieldsQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ManyToManyFieldsQueryFixtureBase.cs index ffc2e36949f..e5de82a1909 100644 --- a/test/EFCore.Specification.Tests/Query/ManyToManyFieldsQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ManyToManyFieldsQueryFixtureBase.cs @@ -7,17 +7,14 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class ManyToManyFieldsQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class ManyToManyFieldsQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "ManyToManyQueryTest"; - public Func GetContextCreator() - => () => CreateContext(); - private ManyToManyData _data; - public ISetSource GetExpectedData() + public override ISetSource GetExpectedData() { if (_data == null) { @@ -30,7 +27,7 @@ public ISetSource GetExpectedData() return _data; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(EntityOne), e => ((EntityOne)e)?.Id }, { typeof(EntityTwo), e => ((EntityTwo)e)?.Id }, @@ -41,7 +38,7 @@ public ISetSource GetExpectedData() { typeof(EntityLeaf), e => ((EntityLeaf)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(EntityOne), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs index cf7ebf60b40..22325363206 100644 --- a/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs @@ -7,17 +7,14 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class ManyToManyQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class ManyToManyQueryFixtureBase : QueryFixtureBase { protected override string StoreName => "ManyToManyQueryTest"; - public Func GetContextCreator() - => () => CreateContext(); - private ManyToManyData _data; - public ISetSource GetExpectedData() + public override ISetSource GetExpectedData() { if (_data == null) { @@ -30,7 +27,7 @@ public ISetSource GetExpectedData() return _data; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(EntityOne), e => ((EntityOne)e)?.Id }, { typeof(EntityTwo), e => ((EntityTwo)e)?.Id }, @@ -56,7 +53,7 @@ public ISetSource GetExpectedData() { typeof(UnidirectionalEntityLeaf), e => ((UnidirectionalEntityLeaf)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(EntityOne), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs deleted file mode 100644 index 7c82cb164db..00000000000 --- a/test/EFCore.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryTestBase.cs +++ /dev/null @@ -1,362 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Query; - -using static Expression; - -public abstract class NonSharedPrimitiveCollectionsQueryTestBase(NonSharedFixture fixture) - : NonSharedModelTestBase(fixture), IClassFixture -{ - #region Support for specific element types - - [ConditionalFact] - public virtual Task Array_of_string() - => TestArray("a", "b"); - - [ConditionalFact] - public virtual Task Array_of_int() - => TestArray(1, 2); - - [ConditionalFact] - public virtual Task Array_of_long() - => TestArray(1L, 2L); - - [ConditionalFact] - public virtual Task Array_of_short() - => TestArray((short)1, (short)2); - - [ConditionalFact] - public virtual Task Array_of_byte() - => TestArray((byte)1, (byte)2); - - [ConditionalFact] - public virtual Task Array_of_double() - => TestArray(1d, 2d); - - [ConditionalFact] - public virtual Task Array_of_float() - => TestArray(1f, 2f); - - [ConditionalFact] - public virtual Task Array_of_decimal() - => TestArray(1m, 2m); - - [ConditionalFact] - public virtual Task Array_of_DateTime() - => TestArray(new DateTime(2023, 1, 1, 12, 30, 0), new DateTime(2023, 1, 2, 12, 30, 0)); - - [ConditionalFact] - public virtual Task Array_of_DateTime_with_milliseconds() - => TestArray(new DateTime(2023, 1, 1, 12, 30, 0, 123), new DateTime(2023, 1, 1, 12, 30, 0, 124)); - - [ConditionalFact] - public virtual Task Array_of_DateTime_with_microseconds() - => TestArray(new DateTime(2023, 1, 1, 12, 30, 0, 123, 456), new DateTime(2023, 1, 1, 12, 30, 0, 123, 457)); - - [ConditionalFact] - public virtual Task Array_of_DateOnly() - => TestArray(new DateOnly(2023, 1, 1), new DateOnly(2023, 1, 2)); - - [ConditionalFact] - public virtual Task Array_of_TimeOnly() - => TestArray(new TimeOnly(12, 30, 0), new TimeOnly(12, 30, 1)); - - [ConditionalFact] - public virtual Task Array_of_TimeOnly_with_milliseconds() - => TestArray(new TimeOnly(12, 30, 0, 123), new TimeOnly(12, 30, 0, 124)); - - [ConditionalFact] - public virtual Task Array_of_TimeOnly_with_microseconds() - => TestArray(new TimeOnly(12, 30, 0, 123, 456), new TimeOnly(12, 30, 0, 124, 457)); - - [ConditionalFact] - public virtual Task Array_of_DateTimeOffset() - => TestArray( - new DateTimeOffset(2023, 1, 1, 12, 30, 0, TimeSpan.FromHours(2)), - new DateTimeOffset(2023, 1, 2, 12, 30, 0, TimeSpan.FromHours(2))); - - [ConditionalFact] - public virtual Task Array_of_bool() - => TestArray(true, false); - - [ConditionalFact] - public virtual Task Array_of_Guid() - => TestArray( - new Guid("dc8c903d-d655-4144-a0fd-358099d40ae1"), - new Guid("008719a5-1999-4798-9cf3-92a78ffa94a2")); - - [ConditionalFact] - public virtual Task Array_of_byte_array() - => TestArray([1, 2], new byte[] { 3, 4 }); - - [ConditionalFact] - public virtual Task Array_of_enum() - => TestArray(MyEnum.Label1, MyEnum.Label2); - - private enum MyEnum { Label1, Label2 } - - [ConditionalFact] - public virtual async Task Multidimensional_array_is_not_supported() - { - var exception = await Assert.ThrowsAsync(() => InitializeAsync( - onModelCreating: mb => mb.Entity().Property(typeof(int[,]), "MultidimensionalArray"))); - Assert.Equal(CoreStrings.PropertyNotMapped("int[,]", "TestEntity", "MultidimensionalArray"), exception.Message); - } - - #endregion Support for specific element types - - [ConditionalFact] - public virtual async Task Column_with_custom_converter() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity() - .Property(m => m.Ints) - .HasConversion( - i => string.Join(",", i!), - s => s.Split(",", StringSplitOptions.None).Select(int.Parse).ToArray(), - new ValueComparer(favorStructuralComparisons: true)), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1, Ints = [1, 2, 3] }, - new TestEntity { Id = 2, Ints = [1, 2, 4] }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 1, 2, 3 }; - var result = await context.Set().SingleAsync(m => m.Ints == ints); - Assert.Equal(1, result.Id); - - // Custom converters allow reading/writing, but not querying, as we have no idea about the internal representation - await AssertTranslationFailed(() => context.Set().SingleAsync(m => m.Ints!.Length == 2)); - } - - [ConditionalFact( - Skip = - "Currently fails because we don't use the element mapping when serializing to JSON, but just do JsonSerializer.Serialize, #30677")] - public virtual async Task Parameter_with_inferred_value_converter() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb - .Entity() - .Property("PropertyWithValueConverter") - .HasConversion(w => w.Value, i => new IntWrapper(i)), - seed: context => - { - var entry1 = context.Add(new TestEntity { Id = 1 }); - entry1.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(8); - var entry2 = context.Add(new TestEntity { Id = 2 }); - entry2.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(9); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new IntWrapper[] { new(1), new(8) }; - var result = await context.Set() - .SingleAsync(m => ints.Count(i => i == EF.Property(m, "PropertyWithValueConverter")) == 1); - Assert.Equal(1, result.Id); - } - - [ConditionalFact] - public virtual async Task Constant_with_inferred_value_converter() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb - .Entity() - .Property("PropertyWithValueConverter") - .HasConversion(w => w.Value, i => new IntWrapper(i)), - seed: context => - { - var entry1 = context.Add(new TestEntity { Id = 1 }); - entry1.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(8); - var entry2 = context.Add(new TestEntity { Id = 2 }); - entry2.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(9); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var result = await context.Set() - .SingleAsync(m - => new IntWrapper[] { new(1), new(8) }.Count(i => i == EF.Property(m, "PropertyWithValueConverter")) == 1); - Assert.Equal(1, result.Id); - } - - private class IntWrapper(int value) - { - public int Value { get; } = value; - } - - [ConditionalFact] - public virtual async Task Inline_collection_in_query_filter() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity().HasQueryFilter(t => new[] { 1, 2, 3 }.Count(i => i > t.Id) == 1), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var result = await context.Set().SingleAsync(); - Assert.Equal(2, result.Id); - } - - [ConditionalFact] - public virtual async Task Project_collection_from_entity_type_with_owned() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => - { - b.Property(b => b.Id).ValueGeneratedNever(); - b.OwnsOne(b => b.Owned); - }), - seed: context => - { - context.AddRange( - new TestEntityWithOwned - { - Id = 1, - Ints = [1, 2], - Owned = new Owned { Foo = 0 } - }, - new TestEntityWithOwned - { - Id = 2, - Ints = [3, 4], - Owned = new Owned { Foo = 1 } - }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var results = await context.Set().Select(t => t.Ints).ToListAsync(); - Assert.Contains(results, r => r?.SequenceEqual([1, 2]) ?? false); - Assert.Contains(results, r => r?.SequenceEqual([3, 4]) ?? false); - } - - private class TestEntityWithOwned - { - public int Id { get; set; } - public int[]? Ints { get; set; } - public Owned Owned { get; set; } = default!; - } - - private class Owned - { - public int Foo { get; set; } - } - - [ConditionalFact] // #37478 - public virtual async Task Subquery_over_primitive_collection_on_inheritance_derived_type() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => - { - mb.Entity(); - mb.Entity(); - }); - - await using var context = contextFactory.CreateContext(); - - _ = await context.Set() - .Where(x => ((SubType)x).Ints.Any()) - .ToListAsync(); - } - - public abstract class BaseType - { - public int Id { get; set; } - } - - public class SubType : BaseType - { - public required int[] Ints { get; set; } - } - - /// - /// A utility that allows easy testing of querying out arbitrary element types from a primitive collection, provided two distinct - /// element values. - /// - protected async Task TestArray( - TElement value1, - TElement value2, - Action? onModelCreating = null) - { - var arrayClrType = typeof(TElement).MakeArrayType(); - - var contextFactory = await InitializeAsync( - onModelCreating: onModelCreating ?? (mb => mb.Entity().Property(arrayClrType, "SomeArray")), - seed: context => - { - var instance1 = new TestEntity { Id = 1 }; - context.Add(instance1); - var array1 = new TElement[2]; - array1.SetValue(value1, 0); - array1.SetValue(value1, 1); - context.Entry(instance1).Property("SomeArray").CurrentValue = array1; - - var instance2 = new TestEntity { Id = 2 }; - context.Add(instance2); - var array2 = new TElement[2]; - array2.SetValue(value1, 0); - array2.SetValue(value2, 1); - context.Entry(instance2).Property("SomeArray").CurrentValue = array2; - - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var entityParam = Parameter(typeof(TestEntity), "m"); - var efPropertyCall = Call( - typeof(EF).GetMethod(nameof(EF.Property), BindingFlags.Public | BindingFlags.Static)!.MakeGenericMethod(arrayClrType), - entityParam, - Constant("SomeArray")); - - var elementParam = Parameter(typeof(TElement), "a"); - var predicate = Lambda>( - Equal( - Call( - EnumerableMethods.CountWithPredicate.MakeGenericMethod(typeof(TElement)), - efPropertyCall, - Lambda( - Equal(elementParam, Constant(value1)), - elementParam)), - Constant(2)), - entityParam); - - var result = await context.Set().SingleAsync(predicate); - Assert.Equal(1, result.Id); - } - - protected class TestContext(DbContextOptions options) : DbContext(options) - { - protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity().Property(e => e.Id).ValueGeneratedNever(); - } - - protected class TestEntity - { - public int Id { get; set; } - public int[]? Ints { get; set; } - } - - protected override string StoreName - => "NonSharedPrimitiveCollectionsTest"; - - protected static async Task AssertTranslationFailed(Func query) - => Assert.Contains( - CoreStrings.TranslationFailed("")[48..], - (await Assert.ThrowsAsync(query)) - .Message); -} diff --git a/test/EFCore.Specification.Tests/Query/NorthwindQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindQueryFixtureBase.cs index cccf1f201e8..bdaec035d41 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindQueryFixtureBase.cs @@ -7,18 +7,15 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class NorthwindQueryFixtureBase : SharedStoreFixtureBase, IFilteredQueryFixtureBase +public abstract class NorthwindQueryFixtureBase : QueryFixtureBase where TModelCustomizer : ITestModelCustomizer, new() { - public Func GetContextCreator() - => CreateContext; - private readonly Dictionary<(bool, string, string), ISetSource> _expectedDataCache = new(); - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => NorthwindData.Instance; - public virtual ISetSource GetFilteredExpectedData(DbContext context) + public override ISetSource GetFilteredExpectedData(DbContext context) { var applyFilters = typeof(TModelCustomizer) == typeof(NorthwindQueryFiltersCustomizer); var tenantPrefix = applyFilters ? ((NorthwindContext)context).TenantPrefix : null; @@ -73,7 +70,7 @@ public virtual ISetSource GetFilteredExpectedData(DbContext context) return expectedData; } - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(Customer), e => ((Customer)e)?.CustomerID }, { typeof(CustomerQuery), e => ((CustomerQuery)e)?.CompanyName }, @@ -87,7 +84,7 @@ public virtual ISetSource GetFilteredExpectedData(DbContext context) { typeof(OrderDetail), e => (((OrderDetail)e)?.OrderID.ToString(), ((OrderDetail)e)?.ProductID.ToString()) } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(Customer), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs index a13939bf68a..b6d420cc954 100644 --- a/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/OwnedQueryTestBase.cs @@ -901,7 +901,7 @@ public virtual Task Union_over_owned_collection(bool async) protected virtual DbContext CreateContext() => Fixture.CreateContext(); - public abstract class OwnedQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase + public abstract class OwnedQueryFixtureBase : QueryFixtureBase { private OwnedQueryData _expectedData; @@ -940,13 +940,10 @@ private static void AssertOrderDetails(IList expectedOrderDetails, } } - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new OwnedQueryData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(OwnedPerson), e => ((OwnedPerson)e)?.Id }, { typeof(Branch), e => ((Branch)e)?.Id }, @@ -967,7 +964,7 @@ public virtual ISetSource GetExpectedData() { typeof(Throned), e => ((Throned)e)?.Property } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(OwnedPerson), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 44ae89ce5bc..514a3bb7cc7 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs @@ -5,6 +5,8 @@ using System.Collections.Frozen; using System.Collections.Immutable; +using static System.Linq.Expressions.Expression; + namespace Microsoft.EntityFrameworkCore.Query; public abstract class PrimitiveCollectionsQueryTestBase(TFixture fixture) : QueryTestBase(fixture) @@ -251,6 +253,25 @@ public virtual Task Inline_collection_Count_with_column_predicate_with_EF_Parame ss => ss.Set().Where(c => EF.Parameter(new[] { 2, 999, 1000 }).Count(i => i > c.Id) == 2), ss => ss.Set().Where(c => new[] { 2, 999, 1000 }.Count(i => i > c.Id) == 2)); + [ConditionalFact] + public virtual async Task Inline_collection_in_query_filter() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity().HasQueryFilter(t => new[] { 1, 2, 3 }.Count(i => i > t.Id) == 1), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1 }, + new TestEntity { Id = 2 }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var result = await context.Set().SingleAsync(); + Assert.Equal(2, result.Id); + } + [ConditionalFact] public virtual Task Parameter_collection_Count() { @@ -995,6 +1016,94 @@ public virtual Task Column_collection_of_nullable_strings_contains_null() public virtual Task Column_collection_of_bools_Contains() => AssertQuery(ss => ss.Set().Where(c => c.Bools.Contains(true))); + [ConditionalFact] + public virtual async Task Column_with_custom_converter() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity() + .Property(m => m.Ints) + .HasConversion( + i => string.Join(",", i!), + s => s.Split(",", StringSplitOptions.None).Select(int.Parse).ToArray(), + new ValueComparer(favorStructuralComparisons: true)), + seed: context => + { + context.AddRange( + new TestEntity { Id = 1, Ints = [1, 2, 3] }, + new TestEntity { Id = 2, Ints = [1, 2, 4] }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new[] { 1, 2, 3 }; + var result = await context.Set().SingleAsync(m => m.Ints == ints); + Assert.Equal(1, result.Id); + + // Custom converters allow reading/writing, but not querying, as we have no idea about the internal representation + await AssertTranslationFailed(() => context.Set().SingleAsync(m => m.Ints!.Length == 2)); + } + + [ConditionalFact( + Skip = + "Currently fails because we don't use the element mapping when serializing to JSON, but just do JsonSerializer.Serialize, #30677")] + public virtual async Task Parameter_with_inferred_value_converter() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb + .Entity() + .Property("PropertyWithValueConverter") + .HasConversion(w => w.Value, i => new IntWrapper(i)), + seed: context => + { + var entry1 = context.Add(new TestEntity { Id = 1 }); + entry1.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(8); + var entry2 = context.Add(new TestEntity { Id = 2 }); + entry2.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(9); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var ints = new IntWrapper[] { new(1), new(8) }; + var result = await context.Set() + .SingleAsync(m => ints.Count(i => i == EF.Property(m, "PropertyWithValueConverter")) == 1); + Assert.Equal(1, result.Id); + } + + [ConditionalFact] + public virtual async Task Constant_with_inferred_value_converter() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb + .Entity() + .Property("PropertyWithValueConverter") + .HasConversion(w => w.Value, i => new IntWrapper(i)), + seed: context => + { + var entry1 = context.Add(new TestEntity { Id = 1 }); + entry1.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(8); + var entry2 = context.Add(new TestEntity { Id = 2 }); + entry2.Property("PropertyWithValueConverter").CurrentValue = new IntWrapper(9); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var result = await context.Set() + .SingleAsync(m + => new IntWrapper[] { new(1), new(8) }.Count(i => i == EF.Property(m, "PropertyWithValueConverter")) == 1); + Assert.Equal(1, result.Id); + } + + [ConditionalFact] + public virtual async Task Multidimensional_array_is_not_supported() + { + var exception = await Assert.ThrowsAsync(() => InitializeNonSharedTest( + onModelCreating: mb => mb.Entity().Property(typeof(int[,]), "MultidimensionalArray"))); + Assert.Equal(CoreStrings.PropertyNotMapped("int[,]", "TestEntity", "MultidimensionalArray"), exception.Message); + } + // C# 14 first-class spans caused MemoryExtensions.Contains to get resolved instead of Enumerable.Contains. // The following tests that the various overloads are all supported. [ConditionalFact] @@ -1626,21 +1735,69 @@ public virtual Task Nested_contains_with_arrays_and_no_inferred_type_mapping() return AssertQuery(ss => ss.Set().Where(e => strings.Contains(ints.Contains(e.Int) ? "one" : "two"))); } + [ConditionalFact] + public virtual async Task Project_collection_from_entity_type_with_owned() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => + { + b.Property(b => b.Id).ValueGeneratedNever(); + b.OwnsOne(b => b.Owned); + }), + seed: context => + { + context.AddRange( + new TestEntityWithOwned + { + Id = 1, + Ints = [1, 2], + Owned = new Owned { Foo = 0 } + }, + new TestEntityWithOwned + { + Id = 2, + Ints = [3, 4], + Owned = new Owned { Foo = 1 } + }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var results = await context.Set().Select(t => t.Ints).ToListAsync(); + Assert.Contains(results, r => r?.SequenceEqual([1, 2]) ?? false); + Assert.Contains(results, r => r?.SequenceEqual([3, 4]) ?? false); + } + + [ConditionalFact] // #37478 + public virtual async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => + { + mb.Entity(); + mb.Entity(); + }); + + await using var context = contextFactory.CreateDbContext(); + + _ = await context.Set() + .Where(x => ((SubType)x).Ints.Any()) + .ToListAsync(); + } + [ConditionalFact] public virtual Task Values_of_enum_casted_to_underlying_value() => AssertQuery(ss => ss.Set().Where(x => Enum.GetValues().Cast().Count(y => y == x.Int) > 0)); - public abstract class PrimitiveCollectionsQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase + public abstract class PrimitiveCollectionsQueryFixtureBase : QueryFixtureBase { private PrimitiveCollectionsData? _expectedData; protected override string StoreName => "PrimitiveCollectionsTest"; - public Func GetContextCreator() - => () => CreateContext(); - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) => modelBuilder.Entity(b => { @@ -1663,15 +1820,15 @@ protected override Task SeedAsync(PrimitiveCollectionsContext context) return context.SaveChangesAsync(); } - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new PrimitiveCollectionsData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(PrimitiveCollectionsEntity), e => ((PrimitiveCollectionsEntity?)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(PrimitiveCollectionsEntity), (e, a) => @@ -1878,6 +2035,49 @@ private static IReadOnlyList CreatePrimitiveArrayEnt } }; } + + #region Non-shared test resources + + protected class TestContext(DbContextOptions options) : DbContext(options) + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity().Property(e => e.Id).ValueGeneratedNever(); + } + + protected class TestEntity + { + public int Id { get; set; } + public int[]? Ints { get; set; } + } + + private class IntWrapper(int value) + { + public int Value { get; } = value; + } + + private class TestEntityWithOwned + { + public int Id { get; set; } + public int[]? Ints { get; set; } + public Owned Owned { get; set; } = default!; + } + + private class Owned + { + public int Foo { get; set; } + } + + public abstract class BaseType + { + public int Id { get; set; } + } + + public class SubType : BaseType + { + public required int[] Ints { get; set; } + } + + #endregion } // Keep it outside so it does not inherit the TFixture. diff --git a/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs new file mode 100644 index 00000000000..4f80180df00 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +public abstract class QueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase + where TContext : DbContext +{ + public virtual Func GetContextCreator() + => CreateContext; + + public virtual Func GetSetSourceCreator() + => context => new DefaultSetSource(context); + + public abstract ISetSource GetExpectedData(); + + public abstract IReadOnlyDictionary EntitySorters { get; } + + public abstract IReadOnlyDictionary EntityAsserters { get; } + + public virtual ISetSource? GetFilteredExpectedData(DbContext context) + => null; + + public virtual void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) + { + } + + public virtual Action GetUseTransaction() + => UseTransaction; + + string IQueryFixtureBase.StoreName + => StoreName; + + #region Non-shared test store support + + private TestStore? _nonSharedTestStore; + + public TestStore GetOrCreateNonSharedTestStore(Func createTestStore) + => _nonSharedTestStore ??= createTestStore(); + + public ITestStoreFactory GetTestStoreFactory() + => TestStoreFactory; + + public TestStore NonSharedTestStore + => _nonSharedTestStore ?? throw new InvalidOperationException("No non-shared test store has been created, call GetOrCreateNonSharedTestStore() first."); + + public override async Task DisposeAsync() + { + await base.DisposeAsync(); + + if (_nonSharedTestStore != null) + { + await _nonSharedTestStore.DisposeAsync(); + _nonSharedTestStore = null; + } + } + + #endregion + + private class DefaultSetSource(DbContext context) : ISetSource + { + private readonly DbContext _context = context; + + public IQueryable Set() + where TEntity : class + => _context.Set(); + } +} + diff --git a/test/EFCore.Specification.Tests/Query/QueryTestBase.cs b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs index 157bc4cffe7..80ec0dff9da 100644 --- a/test/EFCore.Specification.Tests/Query/QueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.Query; -public abstract class QueryTestBase : IClassFixture +public abstract class QueryTestBase : IClassFixture, IAsyncLifetime where TFixture : class, IQueryFixtureBase, new() { private readonly Lazy _queryAsserterCache; @@ -1184,6 +1184,129 @@ protected Task AssertAverage( #endregion + #region Non-shared test support + + private ServiceProvider? _nonSharedServiceProvider; + + protected virtual string NonSharedStoreName + => Fixture.StoreName + "_NonShared"; + + public virtual Task InitializeAsync() + => Task.CompletedTask; + + public virtual async Task DisposeAsync() + { + _nonSharedServiceProvider?.Dispose(); + _nonSharedServiceProvider = null; + } + + protected virtual async Task> InitializeNonSharedTest( + Action? onModelCreating = null, + Action? onConfiguring = null, + Func? addServices = null, + Action? configureConventions = null, + Func? seed = null, + bool usePooling = true, + bool useServiceProvider = true) + where TContext : DbContext + { + _nonSharedServiceProvider?.Dispose(); + _nonSharedServiceProvider = null; + + var testStoreFactory = Fixture.GetTestStoreFactory(); + var testStore = Fixture.GetOrCreateNonSharedTestStore(() => testStoreFactory.Create(NonSharedStoreName)); + + IServiceCollection services = new ServiceCollection(); + + if (useServiceProvider) + { + testStoreFactory.AddProviderServices(services); + } + + services = services.AddSingleton(new NonDisposingLoggerFactoryWrapper(Fixture.ListLoggerFactory)); + + if (onModelCreating != null) + { + services = services.AddSingleton(TestModelSource.GetFactory(onModelCreating, configureConventions)); + } + + addServices?.Invoke(services); + + services = usePooling + ? services.AddPooledDbContextFactory( + typeof(TContext), (s, b) => ConfigureNonSharedOptions(useServiceProvider ? s : null, b, onConfiguring, testStore)) + : services.AddDbContext( + typeof(TContext), + (s, b) => ConfigureNonSharedOptions(useServiceProvider ? s : null, b, onConfiguring, testStore), + ServiceLifetime.Transient, + ServiceLifetime.Singleton); + + _nonSharedServiceProvider = services.BuildServiceProvider(validateScopes: true); + + var contextFactory = new ContextFactory(_nonSharedServiceProvider, usePooling); + + await testStore.InitializeAsync( + _nonSharedServiceProvider, contextFactory.CreateDbContext, seed == null ? null : c => seed((TContext)c)); + + Fixture.ListLoggerFactory.Clear(); + + return contextFactory; + + DbContextOptionsBuilder ConfigureNonSharedOptions( + IServiceProvider? serviceProvider, + DbContextOptionsBuilder optionsBuilder, + Action? onConfiguring, + TestStore testStore) + { + optionsBuilder = Fixture.AddOptions(testStore.AddProviderOptions(optionsBuilder)) + .ConfigureWarnings(w => w.Ignore( + CoreEventId.MappedEntityTypeIgnoredWarning, + CoreEventId.MappedPropertyIgnoredWarning, + CoreEventId.MappedNavigationIgnoredWarning)); + if (serviceProvider == null) + { + optionsBuilder.EnableServiceProviderCaching(false); + } + else + { + optionsBuilder.UseInternalServiceProvider(serviceProvider); + } + + onConfiguring?.Invoke(optionsBuilder); + return optionsBuilder; + } + } + + private sealed class ContextFactory(IServiceProvider serviceProvider, bool usePooling) + : IDbContextFactory + where TContext : DbContext + { + private IDbContextFactory? PooledContextFactory { get; } + = usePooling + ? (IDbContextFactory)serviceProvider.GetRequiredService(typeof(IDbContextFactory)) + : null; + + public TContext CreateDbContext() + => usePooling + ? PooledContextFactory!.CreateDbContext() + : (TContext)serviceProvider.GetRequiredService(typeof(TContext)); + } + + private sealed class NonDisposingLoggerFactoryWrapper(ILoggerFactory inner) : ILoggerFactory + { + public ILogger CreateLogger(string categoryName) + => inner.CreateLogger(categoryName); + + public void AddProvider(ILoggerProvider provider) + => inner.AddProvider(provider); + + public void Dispose() + { + } + } + + #endregion + #region Helpers protected void AssertEqual(T expected, T actual, Action? asserter = null) diff --git a/test/EFCore.Specification.Tests/Query/SpatialQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/SpatialQueryFixtureBase.cs index 4c82aac933e..4e358a1f3fe 100644 --- a/test/EFCore.Specification.Tests/Query/SpatialQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/SpatialQueryFixtureBase.cs @@ -9,17 +9,14 @@ namespace Microsoft.EntityFrameworkCore.Query; #nullable disable -public abstract class SpatialQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class SpatialQueryFixtureBase : QueryFixtureBase { private GeometryFactory _geometryFactory; - public Func GetContextCreator() - => () => CreateContext(); - - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => new SpatialData(GeometryFactory); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(PointEntity), e => ((PointEntity)e)?.Id }, { typeof(LineStringEntity), e => ((LineStringEntity)e)?.Id }, @@ -28,7 +25,7 @@ public virtual ISetSource GetExpectedData() { typeof(GeoPointEntity), e => ((GeoPointEntity)e)?.Id }, }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(PointEntity), (e, a) => diff --git a/test/EFCore.Specification.Tests/Query/Translations/BasicTypesQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/Translations/BasicTypesQueryFixtureBase.cs index 08611b027bc..c3f8ee4841d 100644 --- a/test/EFCore.Specification.Tests/Query/Translations/BasicTypesQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/Translations/BasicTypesQueryFixtureBase.cs @@ -5,16 +5,13 @@ namespace Microsoft.EntityFrameworkCore.Query.Translations; -public abstract class BasicTypesQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase +public abstract class BasicTypesQueryFixtureBase : QueryFixtureBase { private BasicTypesData? _expectedData; protected override string StoreName => "BasicTypesTest"; - public Func GetContextCreator() - => CreateContext; - protected override Task SeedAsync(BasicTypesContext context) { var data = new BasicTypesData(); @@ -23,16 +20,16 @@ protected override Task SeedAsync(BasicTypesContext context) return context.SaveChangesAsync(); } - public virtual ISetSource GetExpectedData() + public override ISetSource GetExpectedData() => _expectedData ??= new BasicTypesData(); - public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> + public override IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(BasicTypesEntity), e => ((BasicTypesEntity?)e)?.Id }, { typeof(NullableBasicTypesEntity), e => ((NullableBasicTypesEntity?)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); - public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> + public override IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(BasicTypesEntity), (e, a) => diff --git a/test/EFCore.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs b/test/EFCore.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs index 7b94ca4ed3d..b4cd0b968eb 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/BulkUpdatesAsserter.cs @@ -2,11 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. #nullable disable -using Microsoft.EntityFrameworkCore.BulkUpdates; namespace Microsoft.EntityFrameworkCore.TestUtilities; -public class BulkUpdatesAsserter(IBulkUpdatesFixtureBase queryFixture, Func rewriteServerQueryExpression) +public class BulkUpdatesAsserter(IQueryFixtureBase queryFixture, Func rewriteServerQueryExpression) { private readonly Func _contextCreator = queryFixture.GetContextCreator(); private readonly Action _useTransaction = queryFixture.GetUseTransaction(); diff --git a/test/EFCore.Specification.Tests/TestUtilities/QueryAsserter.cs b/test/EFCore.Specification.Tests/TestUtilities/QueryAsserter.cs index 9a3ecac52af..3fe1c399fa3 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/QueryAsserter.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/QueryAsserter.cs @@ -40,7 +40,7 @@ protected virtual void AssertRogueExecution(int expectedCount, IQueryable querya } protected ISetSource GetExpectedData(DbContext context, bool filteredQuery) - => filteredQuery ? ((IFilteredQueryFixtureBase)QueryFixture).GetFilteredExpectedData(context) : _expectedData; + => filteredQuery ? QueryFixture.GetFilteredExpectedData(context)! : _expectedData; public virtual async Task AssertSingleResult( Expression> actualSyncQuery, diff --git a/test/EFCore.Specification.Tests/Types/TypeEntity.cs b/test/EFCore.Specification.Tests/Types/TypeEntity.cs index 4923e60dcd3..ef9010781f2 100644 --- a/test/EFCore.Specification.Tests/Types/TypeEntity.cs +++ b/test/EFCore.Specification.Tests/Types/TypeEntity.cs @@ -9,4 +9,6 @@ public class TypeEntity public required T Value { get; set; } public required T OtherValue { get; set; } + + public required T[] ArrayValue { get; set; } } diff --git a/test/EFCore.Specification.Tests/Types/TypeFixtureBase.cs b/test/EFCore.Specification.Tests/Types/TypeFixtureBase.cs index 78e400d813c..5480691e4f0 100644 --- a/test/EFCore.Specification.Tests/Types/TypeFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Types/TypeFixtureBase.cs @@ -34,13 +34,15 @@ protected override async Task SeedAsync(DbContext context) { Id = 1, Value = Value, - OtherValue = OtherValue + OtherValue = OtherValue, + ArrayValue = [Value, Value] }, new() { Id = 2, Value = OtherValue, - OtherValue = Value + OtherValue = Value, + ArrayValue = [Value, OtherValue] }); await context.SaveChangesAsync(); diff --git a/test/EFCore.Specification.Tests/Types/TypeTestBase.cs b/test/EFCore.Specification.Tests/Types/TypeTestBase.cs index 9a448cc3c47..6098ff99c58 100644 --- a/test/EFCore.Specification.Tests/Types/TypeTestBase.cs +++ b/test/EFCore.Specification.Tests/Types/TypeTestBase.cs @@ -11,7 +11,7 @@ public abstract class TypeTestBase(TFixture fixture) : IClassFixtur where T : notnull { [ConditionalFact] - public async virtual Task Equality_in_query_with_parameter() + public virtual async Task Equality_in_query_with_parameter() { await using var context = Fixture.CreateContext(); @@ -21,7 +21,7 @@ public async virtual Task Equality_in_query_with_parameter() } [ConditionalFact] - public async virtual Task Equality_in_query_with_constant() + public virtual async Task Equality_in_query_with_constant() { await using var context = Fixture.CreateContext(); @@ -38,6 +38,16 @@ public async virtual Task Equality_in_query_with_constant() Assert.Equal(Fixture.Value, result.Value, Fixture.Comparer); } + [ConditionalFact] + public virtual async Task Primitive_collection_in_query() + { + await using var context = Fixture.CreateContext(); + + var value = Fixture.Value; + var result = await context.Set>().SingleAsync(e => e.ArrayValue.Count(a => a.Equals(value)) == 2); + Assert.Equal(1, result.Id); + } + [ConditionalFact] public virtual async Task SaveChanges() { @@ -51,6 +61,7 @@ public virtual async Task SaveChanges() Assert.Equal(Fixture.OtherValue, result.Value, Fixture.Comparer); // Revert back to the original value to avoid affecting other tests (note that test parallelization is disabled) + // We do not use a transaction since not all databases support them (e.g. Cosmos). entity.Value = Fixture.Value; await context.SaveChangesAsync(); } diff --git a/test/EFCore.SqlServer.FunctionalTests/BatchingTest.cs b/test/EFCore.SqlServer.FunctionalTests/BatchingTest.cs index 092f20c0fb6..24bdab3d376 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BatchingTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BatchingTest.cs @@ -132,7 +132,7 @@ public Task Insertion_order_is_preserved(int maxBatchSize) var blogId = new Guid(); return TestHelpers.ExecuteWithStrategyInTransactionAsync( - () => (BloggingContext)Fixture.CreateContext(maxBatchSize: maxBatchSize), + () => Fixture.CreateContext(maxBatchSize: maxBatchSize), UseTransaction, async context => { var owner = new Owner(); @@ -217,7 +217,7 @@ public async Task Deadlock_on_inserts_and_deletes_with_dependents_is_handled_cor async Task RemoveAndAddPosts(Blog blog) { - using var context = (BloggingContext)Fixture.CreateContext(useConnectionString: true); + using var context = Fixture.CreateContext(useConnectionString: true); context.Attach(blog); blog.Posts.Clear(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs deleted file mode 100644 index 71a755d1e22..00000000000 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs +++ /dev/null @@ -1,1210 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.SqlServer.Internal; - -namespace Microsoft.EntityFrameworkCore.Query; - -#nullable disable -using static Expression; - -public class NonSharedPrimitiveCollectionsQuerySqlServerTest(NonSharedFixture fixture) - : NonSharedPrimitiveCollectionsQueryRelationalTestBase(fixture) -{ - protected override DbContextOptionsBuilder SetParameterizedCollectionMode( - DbContextOptionsBuilder optionsBuilder, - ParameterTranslationMode parameterizedCollectionMode) - { - new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); - - return optionsBuilder; - } - - #region Support for specific element types - - public override async Task Array_of_string() - { - await base.Array_of_string(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] nvarchar(max) '$') AS [s] - WHERE [s].[value] = N'a') = 2 -"""); - } - - public override async Task Array_of_int() - { - await base.Array_of_int(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] int '$') AS [s] - WHERE [s].[value] = 1) = 2 -"""); - } - - public override async Task Array_of_long() - { - await base.Array_of_long(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] bigint '$') AS [s] - WHERE [s].[value] = CAST(1 AS bigint)) = 2 -"""); - } - - public override async Task Array_of_short() - { - await base.Array_of_short(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] smallint '$') AS [s] - WHERE [s].[value] = CAST(1 AS smallint)) = 2 -"""); - } - - [ConditionalFact] - public override Task Array_of_byte() - => base.Array_of_byte(); - - public override async Task Array_of_double() - { - await base.Array_of_double(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] float '$') AS [s] - WHERE [s].[value] = 1.0E0) = 2 -"""); - } - - public override async Task Array_of_float() - { - await base.Array_of_float(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] real '$') AS [s] - WHERE [s].[value] = CAST(1 AS real)) = 2 -"""); - } - - public override async Task Array_of_decimal() - { - await base.Array_of_decimal(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] decimal(18,2) '$') AS [s] - WHERE [s].[value] = 1.0) = 2 -"""); - } - - public override async Task Array_of_DateTime() - { - await base.Array_of_DateTime(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] datetime2 '$') AS [s] - WHERE [s].[value] = '2023-01-01T12:30:00.0000000') = 2 -"""); - } - - public override async Task Array_of_DateTime_with_milliseconds() - { - await base.Array_of_DateTime_with_milliseconds(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] datetime2 '$') AS [s] - WHERE [s].[value] = '2023-01-01T12:30:00.1230000') = 2 -"""); - } - - public override async Task Array_of_DateTime_with_microseconds() - { - await base.Array_of_DateTime_with_microseconds(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] datetime2 '$') AS [s] - WHERE [s].[value] = '2023-01-01T12:30:00.1234560') = 2 -"""); - } - - public override async Task Array_of_DateOnly() - { - await base.Array_of_DateOnly(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] date '$') AS [s] - WHERE [s].[value] = '2023-01-01') = 2 -"""); - } - - public override async Task Array_of_TimeOnly() - { - await base.Array_of_TimeOnly(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] time '$') AS [s] - WHERE [s].[value] = '12:30:00') = 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_milliseconds() - { - await base.Array_of_TimeOnly_with_milliseconds(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] time '$') AS [s] - WHERE [s].[value] = '12:30:00.123') = 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_microseconds() - { - await base.Array_of_TimeOnly_with_microseconds(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] time '$') AS [s] - WHERE [s].[value] = '12:30:00.123456') = 2 -"""); - } - - public override async Task Array_of_DateTimeOffset() - { - await base.Array_of_DateTimeOffset(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] datetimeoffset '$') AS [s] - WHERE [s].[value] = '2023-01-01T12:30:00.0000000+02:00') = 2 -"""); - } - - public override async Task Array_of_bool() - { - await base.Array_of_bool(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] bit '$') AS [s] - WHERE [s].[value] = CAST(1 AS bit)) = 2 -"""); - } - - public override async Task Array_of_Guid() - { - await base.Array_of_Guid(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] uniqueidentifier '$') AS [s] - WHERE [s].[value] = 'dc8c903d-d655-4144-a0fd-358099d40ae1') = 2 -"""); - } - - public override async Task Array_of_byte_array() - { - await base.Array_of_byte_array(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] varbinary(max) '$') AS [s] - WHERE [s].[value] = 0x0102) = 2 -"""); - } - - public override async Task Array_of_enum() - { - await base.Array_of_enum(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON([t].[SomeArray]) WITH ([value] int '$') AS [s] - WHERE [s].[value] = 0) = 2 -"""); - } - - [ConditionalFact] - public override Task Multidimensional_array_is_not_supported() - => base.Multidimensional_array_is_not_supported(); - - #endregion Support for specific element types - - #region Specific element types in ordered context - - // When we don't need to preserve the collection's ordering (e.g. when Contains/Count is composed on top of it), we use OPENJSON with - // WITH, which handles all conversions out of JSON well. - // However, OPENJSON with WITH doesn't support preserving the ordering, so when that's needed we switch to OPENJSON without WITH, at - // which point we need to manually convert JSON values into their relational counterparts (this isn't always possible, e.g. varbinary - // which is base64 in JSON). - // The regular element type tests above test in unordered context, so we repeat them here but with an order-preserving context. - - [ConditionalFact] - public virtual async Task Ordered_array_of_string() - { - await TestOrderedArray("a", "b"); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT [s].[value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = N'a') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_int() - { - await TestOrderedArray(1, 2); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS int) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = 1) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_long() - { - await TestOrderedArray(1L, 2L); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS bigint) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = CAST(1 AS bigint)) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_short() - { - await TestOrderedArray((short)1, (short)2); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS smallint) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = CAST(1 AS smallint)) = 2 -"""); - } - - // On relational databases, byte[] gets mapped to a special binary data type, which isn't queryable as a regular primitive collection. - [ConditionalFact] - public virtual async Task Ordered_array_of_byte() - => await AssertTranslationFailed(() => TestOrderedArray((byte)1, (byte)2)); - - [ConditionalFact] - public virtual async Task Ordered_array_of_double() - { - await TestOrderedArray(1d, 2d); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS float) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = 1.0E0) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_float() - { - await TestOrderedArray(1f, 2f); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS real) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = CAST(1 AS real)) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_decimal() - { - await TestOrderedArray(1m, 2m); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS decimal(18,2)) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = 1.0) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_DateTime() - { - await TestOrderedArray(new DateTime(2023, 1, 1, 12, 30, 0), new DateTime(2023, 1, 2, 12, 30, 0)); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS datetime2) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = '2023-01-01T12:30:00.0000000') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_DateOnly() - { - await TestOrderedArray(new DateOnly(2023, 1, 1), new DateOnly(2023, 1, 2)); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS date) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = '2023-01-01') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_TimeOnly() - { - await TestOrderedArray(new TimeOnly(12, 30, 0), new TimeOnly(12, 30, 1)); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS time) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = '12:30:00') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_DateTimeOffset() - { - await TestOrderedArray( - new DateTimeOffset(2023, 1, 1, 12, 30, 0, TimeSpan.FromHours(2)), - new DateTimeOffset(2023, 1, 2, 12, 30, 0, TimeSpan.FromHours(2))); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS datetimeoffset) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = '2023-01-01T12:30:00.0000000+02:00') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_bool() - { - await TestOrderedArray(true, false); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS bit) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = CAST(1 AS bit)) = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_guid() - { - await TestOrderedArray( - new Guid("dc8c903d-d655-4144-a0fd-358099d40ae1"), - new Guid("008719a5-1999-4798-9cf3-92a78ffa94a2")); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS uniqueidentifier) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = 'dc8c903d-d655-4144-a0fd-358099d40ae1') = 2 -"""); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_byte_array() - { - var exception = await Assert.ThrowsAsync(() => TestOrderedArray([1, 2], new byte[] { 3, 4 })); - - Assert.Equal(SqlServerStrings.QueryingOrderedBinaryJsonCollectionsNotSupported, exception.Message); - } - - [ConditionalFact] - public virtual async Task Ordered_array_of_enum() - { - await TestOrderedArray(MyEnum.Label1, MyEnum.Label2); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM ( - SELECT CAST([s].[value] AS int) AS [value] - FROM OPENJSON([t].[SomeArray]) AS [s] - ORDER BY CAST([s].[key] AS int) - OFFSET 1 ROWS - ) AS [s0] - WHERE [s0].[value] = 0) = 2 -"""); - } - - private enum MyEnum { Label1, Label2 } - - private async Task TestOrderedArray( - TElement value1, - TElement value2, - Action onModelCreating = null) - { - var arrayClrType = typeof(TElement).MakeArrayType(); - - var contextFactory = await InitializeAsync( - onModelCreating: onModelCreating ?? (mb => mb.Entity().Property(arrayClrType, "SomeArray")), - seed: context => - { - var instance1 = new TestEntity { Id = 1 }; - context.Add(instance1); - var array1 = new TElement[3]; - array1.SetValue(value1, 0); // We have an extra copy of the first value which we'll Skip, to preserve the ordering - array1.SetValue(value1, 1); - array1.SetValue(value1, 2); - context.Entry(instance1).Property("SomeArray").CurrentValue = array1; - - var instance2 = new TestEntity { Id = 2 }; - context.Add(instance2); - var array2 = new TElement[3]; - array2.SetValue(value1, 0); - array2.SetValue(value1, 1); - array2.SetValue(value2, 2); - context.Entry(instance2).Property("SomeArray").CurrentValue = array2; - - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var entityParam = Parameter(typeof(TestEntity), "m"); - var efPropertyCall = Call( - typeof(EF).GetMethod(nameof(EF.Property), BindingFlags.Public | BindingFlags.Static)!.MakeGenericMethod(arrayClrType), - entityParam, - Constant("SomeArray")); - - var elementParam = Parameter(typeof(TElement), "a"); - var predicate = Lambda>( - Equal( - Call( - CountWithPredicateMethod.MakeGenericMethod(typeof(TElement)), - Call( - SkipMethod.MakeGenericMethod(typeof(TElement)), - efPropertyCall, - Constant(1)), - Lambda(Equal(elementParam, Constant(value1)), elementParam)), - Constant(2)), - entityParam); - - // context.Set().SingleAsync(m => EF.Property(m, "SomeArray").Skip(1).Count(a => a == ) == 2) - var result = await context.Set().SingleAsync(predicate); - Assert.Equal(1, result.Id); - } - - private static readonly MethodInfo CountWithPredicateMethod - = typeof(Enumerable).GetRuntimeMethods().Single(m => m.Name == nameof(Enumerable.Count) && m.GetParameters().Length == 2); - - private static readonly MethodInfo SkipMethod - = typeof(Enumerable).GetRuntimeMethods().Single(m => m.Name == nameof(Enumerable.Skip) && m.GetParameters().Length == 2); - - #endregion - - public override async Task Column_with_custom_converter() - { - await base.Column_with_custom_converter(); - - AssertSql( - """ -@ints='1,2,3' (Size = 4000) - -SELECT TOP(2) [t].[Id], [t].[Ints] -FROM [TestEntity] AS [t] -WHERE [t].[Ints] = @ints -"""); - } - - public override async Task Parameter_with_inferred_value_converter() - { - await base.Parameter_with_inferred_value_converter(); - - AssertSql(""); - } - - #region Type mapping inference - - public override async Task Constant_with_inferred_value_converter() - { - await base.Constant_with_inferred_value_converter(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints], [t].[PropertyWithValueConverter] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (CAST(1 AS int)), (8)) AS [v]([Value]) - WHERE [v].[Value] = [t].[PropertyWithValueConverter]) = 1 -"""); - } - - public override async Task Inline_collection_in_query_filter() - { - await base.Inline_collection_in_query_filter(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Ints] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (CAST(1 AS int)), (2), (3)) AS [v]([Value]) - WHERE [v].[Value] > [t].[Id]) = 1 -"""); - } - - public override async Task Column_collection_inside_json_owned_entity() - { - await base.Column_collection_inside_json_owned_entity(); - - AssertSql( - """ -SELECT TOP(2) [t].[Id], [t].[Owned] -FROM [TestOwner] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON(JSON_QUERY([t].[Owned], '$.Strings')) AS [s]) = 2 -""", - // - """ -SELECT TOP(2) [t].[Id], [t].[Owned] -FROM [TestOwner] AS [t] -WHERE JSON_VALUE([t].[Owned], '$.Strings[1]') = N'bar' -"""); - } - - public override async Task Project_collection_from_entity_type_with_owned() - { - await base.Project_collection_from_entity_type_with_owned(); - - AssertSql( - """ -SELECT [t].[Ints] -FROM [TestEntityWithOwned] AS [t] -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); - - switch (mode) - { - case ParameterTranslationMode.Constant: - { - AssertSql( - """ -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) - WHERE [i].[Value] > [t].[Id]) = 1 -"""); - break; - } - - case ParameterTranslationMode.Parameter: - { - AssertSql( - """ -@ids='[2,999]' (Size = 4000) - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] - WHERE [i].[value] > [t].[Id]) = 1 -"""); - break; - } - - case ParameterTranslationMode.MultipleParameters: - { - AssertSql( - """ -@ids1='2' -@ids2='999' - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) - WHERE [i].[Value] > [t].[Id]) = 1 -"""); - break; - } - - default: - throw new NotImplementedException(); - } - } - - public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode(mode); - - switch (mode) - { - case ParameterTranslationMode.Constant: - { - AssertSql( - """ -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (2, 999) -"""); - break; - } - - case ParameterTranslationMode.Parameter: - { - AssertSql( - """ -@ints='[2,999]' (Size = 4000) - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN ( - SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] -) -"""); - break; - } - - case ParameterTranslationMode.MultipleParameters: - { - AssertSql( - """ -@ints1='2' -@ints2='999' - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (@ints1, @ints2) -"""); - break; - } - - default: - throw new NotImplementedException(); - } - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); - - AssertSql( - """ -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) - WHERE [i].[Value] > [t].[Id]) = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); - - AssertSql( - """ -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (2, 999) -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( - ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); - - AssertSql( - """ -@ids='[2,999]' (Size = 4000) - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] - WHERE [i].[value] > [t].[Id]) = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); - - AssertSql( - """ -@ints='[2,999]' (Size = 4000) - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN ( - SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] -) -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( - ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); - - AssertSql( - """ -@ids1='2' -@ids2='999' - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE ( - SELECT COUNT(*) - FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) - WHERE [i].[Value] > [t].[Id]) = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); - - AssertSql( - """ -@ints1='2' -@ints2='999' - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (@ints1, @ints2) -"""); - } - - public override async Task Parameter_collection_Contains_parameter_bucketization() - { - await base.Parameter_collection_Contains_parameter_bucketization(); - - AssertSql( - """ -@ints1='2' -@ints2='999' -@ints3='2' -@ints4='2' -@ints5='2' -@ints6='2' -@ints7='2' -@ints8='2' -@ints9='2' -@ints10='2' -@ints11='2' -@ints12='2' -@ints13='2' -@ints14='2' -@ints15='2' -@ints16='2' -@ints17='2' -@ints18='2' -@ints19='2' -@ints20='2' - -SELECT [t].[Id] -FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) -"""); - } - - public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() - { - await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); - - AssertSql( - """ -SELECT [b].[Id], [b].[Discriminator], [b].[Ints] -FROM [BaseType] AS [b] -WHERE EXISTS ( - SELECT 1 - FROM OPENJSON([b].[Ints]) AS [i]) -"""); - } - - [ConditionalFact] - public virtual async Task Same_parameter_with_different_type_mappings() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => - { - b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"); - b.Property(typeof(DateTime), "DateTime2").HasColumnType("datetime2"); - })); - - await using var context = contextFactory.CreateContext(); - - var dateTimes = new[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00) }; - - _ = await context.Set() - .Where(m => - dateTimes.Contains(EF.Property(m, "DateTime")) - && dateTimes.Contains(EF.Property(m, "DateTime2"))) - .ToArrayAsync(); - - AssertSql( - """ -@dateTimes1='2020-01-01T12:30:00.0000000' (DbType = DateTime) -@dateTimes2='2020-01-02T12:30:00.0000000' (DbType = DateTime) -@dateTimes3='2020-01-01T12:30:00.0000000' -@dateTimes4='2020-01-02T12:30:00.0000000' - -SELECT [t].[Id], [t].[DateTime], [t].[DateTime2], [t].[Ints] -FROM [TestEntity] AS [t] -WHERE [t].[DateTime] IN (@dateTimes1, @dateTimes2) AND [t].[DateTime2] IN (@dateTimes3, @dateTimes4) -"""); - } - - [ConditionalFact] - public virtual async Task Same_collection_with_default_type_mapping_and_uninferrable_context() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => b.Property(typeof(DateTime), "DateTime"))); - - await using var context = contextFactory.CreateContext(); - - var dateTimes = new DateTime?[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00), null }; - - _ = await context.Set() - .Where(m => dateTimes.Any(d => d == EF.Property(m, "DateTime") && d != null)) - .ToArrayAsync(); - - AssertSql( - """ -@dateTimes1='2020-01-01T12:30:00.0000000' -@dateTimes2='2020-01-02T12:30:00.0000000' -@dateTimes3=NULL (DbType = DateTime2) - -SELECT [t].[Id], [t].[DateTime], [t].[Ints] -FROM [TestEntity] AS [t] -WHERE EXISTS ( - SELECT 1 - FROM (VALUES (@dateTimes1), (@dateTimes2), (@dateTimes3)) AS [d]([Value]) - WHERE [d].[Value] = [t].[DateTime] AND [d].[Value] IS NOT NULL) -"""); - } - - [ConditionalFact] - public virtual async Task Same_collection_with_non_default_type_mapping_and_uninferrable_context() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"))); - - await using var context = contextFactory.CreateContext(); - - var dateTimes = new DateTime?[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00), null }; - - var exception = await Assert.ThrowsAsync(() => context.Set() - .Where(m => dateTimes.Any(d => d == EF.Property(m, "DateTime") && d != null)) - .ToArrayAsync()); - Assert.Equal(RelationalStrings.ConflictingTypeMappingsInferredForColumn("Value"), exception.Message); - } - - [ConditionalFact] - public virtual async Task Same_collection_with_conflicting_type_mappings_not_supported() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => - { - b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"); - b.Property(typeof(DateTime), "DateTime2").HasColumnType("datetime2"); - })); - - await using var context = contextFactory.CreateContext(); - - var dateTimes = new[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00) }; - - var exception = await Assert.ThrowsAsync(() => context.Set() - .Where(m => dateTimes - .Any(d => d == EF.Property(m, "DateTime") && d == EF.Property(m, "DateTime2"))) - .ToArrayAsync()); - Assert.Equal(RelationalStrings.ConflictingTypeMappingsInferredForColumn("Value"), exception.Message); - } - - [ConditionalFact] - public virtual async Task Infer_inline_collection_type_mapping() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(b => b.Property("DateTime").HasColumnType("datetime"))); - - await using var context = contextFactory.CreateContext(); - - _ = await context.Set() - .Where(b => new[] { new DateTime(2020, 1, 1), EF.Property(b, "DateTime") }[0] == new DateTime(2020, 1, 1)) - .ToArrayAsync(); - - AssertSql( - """ -SELECT [t].[Id], [t].[DateTime], [t].[Ints] -FROM [TestEntity] AS [t] -WHERE ( - SELECT [v].[Value] - FROM (VALUES (0, CAST('2020-01-01T00:00:00.000' AS datetime)), (1, [t].[DateTime])) AS [v]([_ord], [Value]) - ORDER BY [v].[_ord] - OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = '2020-01-01T00:00:00.000' -"""); - } - - #endregion Type mapping inference - - [ConditionalFact] - public virtual async Task Ordered_collection_with_split_query() - { - var contextFactory = await InitializeAsync( - onModelCreating: mb => mb.Entity(), - seed: context => - { - context.Add(new Context32976.Principal { Ints = [2, 3, 4] }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - _ = await context.Set() - .Where(p => p.Ints.Skip(1).Contains(3)) - .Include(p => p.Dependents) - .AsSplitQuery() - .SingleAsync(); - } - - public class Context32976(DbContextOptions options) : DbContext(options) - { - public class Principal - { - public int Id { get; set; } - public List Ints { get; set; } - public List Dependents { get; set; } - } - - public class Dependent - { - public int Id { get; set; } - public Principal Principal { get; set; } - } - } - - [ConditionalFact] - public virtual void Check_all_tests_overridden() - => TestHelpers.AssertAllMethodsOverridden(GetType()); - - protected override ITestStoreFactory TestStoreFactory - => SqlServerTestStoreFactory.Instance; -} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs index 6fcf185ce0e..0c8b8425307 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs @@ -463,6 +463,21 @@ public override Task Inline_collection_Contains_with_IEnumerable_EF_Parameter() public override Task Inline_collection_Count_with_column_predicate_with_EF_Parameter() => AssertCompatibilityLevelTooLow(() => base.Inline_collection_Count_with_column_predicate_with_EF_Parameter()); + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (2), (3)) AS [v]([Value]) + WHERE [v].[Value] > [t].[Id]) = 1 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -1016,6 +1031,206 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n Assert.DoesNotContain("OPENJSON", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + switch (mode) + { + case ParameterTranslationMode.Parameter: + await AssertCompatibilityLevelTooLow( + () => base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode)); + break; + + case ParameterTranslationMode.Constant: + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + + public override Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( + ParameterTranslationMode mode) + => AssertCompatibilityLevelTooLow( + () => base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode)); + + public override Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + => AssertCompatibilityLevelTooLow( + () => base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode)); + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + } + + public override async Task Parameter_collection_Contains_parameter_bucketization() + { + await base.Parameter_collection_Contains_parameter_bucketization(); + + AssertSql( + """ +@ints1='2' +@ints2='999' +@ints3='2' +@ints4='2' +@ints5='2' +@ints6='2' +@ints7='2' +@ints8='2' +@ints9='2' +@ints10='2' +@ints11='2' +@ints12='2' +@ints13='2' +@ints14='2' +@ints15='2' +@ints16='2' +@ints17='2' +@ints18='2' +@ints19='2' +@ints20='2' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) +"""); + } + public override async Task Static_readonly_collection_List_of_ints_Contains_int() { await base.Static_readonly_collection_List_of_ints_Contains_int(); @@ -1102,6 +1317,49 @@ await context.Database.SqlQuery($"SELECT [Bools] AS [Value] FROM [Primit .SingleAsync()); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' (Size = 4000) + +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE [t].[Ints] = @ints +"""); + } + + public override Task Column_collection_inside_json_owned_entity() + => AssertCompatibilityLevelTooLow(() => base.Column_collection_inside_json_owned_entity()); + + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(""); + } + + public override async Task Constant_with_inferred_value_converter() + { + await base.Constant_with_inferred_value_converter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[PropertyWithValueConverter] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (8)) AS [v]([Value]) + WHERE [v].[Value] = [t].[PropertyWithValueConverter]) = 1 +"""); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -1617,6 +1875,20 @@ public override async Task Project_inline_collection_with_Concat() AssertSql(); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT [t].[Ints] +FROM [TestEntityWithOwned] AS [t] +"""); + } + + public override Task Subquery_over_primitive_collection_on_inheritance_derived_type() + => AssertCompatibilityLevelTooLow(() => base.Subquery_over_primitive_collection_on_inheritance_derived_type()); + public override async Task Nested_contains_with_Lists_and_no_inferred_type_mapping() { await base.Nested_contains_with_Lists_and_no_inferred_type_mapping(); @@ -1830,6 +2102,15 @@ public virtual async Task Parameter_collection_with_null_value_Contains_null_220 // No SQL assertion as the SQL is huge } + protected override DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); + + return optionsBuilder; + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index e32f1269e0b..1b943eefbaa 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -471,6 +471,21 @@ FROM OPENJSON(@p) WITH ([value] int '$') AS [p0] """); } + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (2), (3)) AS [v]([Value]) + WHERE [v].[Value] > [t].[Id]) = 1 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -1033,6 +1048,245 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n Assert.Contains("OPENJSON(@ints) WITH ([Value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ints='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ids='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ints='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + } + + public override async Task Parameter_collection_Contains_parameter_bucketization() + { + await base.Parameter_collection_Contains_parameter_bucketization(); + + AssertSql( + """ +@ints1='2' +@ints2='999' +@ints3='2' +@ints4='2' +@ints5='2' +@ints6='2' +@ints7='2' +@ints8='2' +@ints9='2' +@ints10='2' +@ints11='2' +@ints12='2' +@ints13='2' +@ints14='2' +@ints15='2' +@ints16='2' +@ints17='2' +@ints18='2' +@ints19='2' +@ints20='2' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) +"""); + } + public override async Task Static_readonly_collection_List_of_ints_Contains_int() { await base.Static_readonly_collection_List_of_ints_Contains_int(); @@ -1200,6 +1454,66 @@ await context.Database.SqlQuery($"SELECT [Bools] AS [Value] FROM [Primit .SingleAsync()); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' (Size = 4000) + +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE [t].[Ints] = @ints +"""); + } + + public override async Task Column_collection_inside_json_owned_entity() + { + await base.Column_collection_inside_json_owned_entity(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(JSON_QUERY([t].[Owned], '$.Strings')) AS [s]) = 2 +""", + // + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE JSON_VALUE([t].[Owned], '$.Strings[1]') = N'bar' +"""); + } + + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(""); + } + + public override async Task Constant_with_inferred_value_converter() + { + await base.Constant_with_inferred_value_converter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[PropertyWithValueConverter] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (8)) AS [v]([Value]) + WHERE [v].[Value] = [t].[PropertyWithValueConverter]) = 1 +"""); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -2377,6 +2691,31 @@ public override async Task Project_inline_collection_with_Concat() AssertSql(); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT [t].[Ints] +FROM [TestEntityWithOwned] AS [t] +"""); + } + + public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); + + AssertSql( + """ +SELECT [b].[Id], [b].[Discriminator], [b].[Ints] +FROM [BaseType] AS [b] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON([b].[Ints]) AS [i]) +"""); + } + public override async Task Nested_contains_with_Lists_and_no_inferred_type_mapping() { await base.Nested_contains_with_Lists_and_no_inferred_type_mapping(); @@ -2576,6 +2915,15 @@ SELECT COUNT(*) """); } + protected override DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); + + return optionsBuilder; + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs index eda486e0110..171cc38ddf9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs @@ -640,6 +640,21 @@ FROM OPENJSON(@p) WITH ([value] int '$') AS [p0] """); } + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (2), (3)) AS [v]([Value]) + WHERE [v].[Value] > [t].[Id]) = 1 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -1205,6 +1220,245 @@ SELECT NULL AS [Value] """); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 7) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ints='[2,999]' (Size = 7) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ids='[2,999]' (Size = 7) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ints='[2,999]' (Size = 7) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + } + + public override async Task Parameter_collection_Contains_parameter_bucketization() + { + await base.Parameter_collection_Contains_parameter_bucketization(); + + AssertSql( + """ +@ints1='2' +@ints2='999' +@ints3='2' +@ints4='2' +@ints5='2' +@ints6='2' +@ints7='2' +@ints8='2' +@ints9='2' +@ints10='2' +@ints11='2' +@ints12='2' +@ints13='2' +@ints14='2' +@ints15='2' +@ints16='2' +@ints17='2' +@ints18='2' +@ints19='2' +@ints20='2' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) +"""); + } + public override async Task Static_readonly_collection_List_of_ints_Contains_int() { await base.Static_readonly_collection_List_of_ints_Contains_int(); @@ -1360,6 +1614,66 @@ await context.Database.SqlQuery($"SELECT [Bools] AS [Value] FROM [Primit .SingleAsync()); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' (Size = 4000) + +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE [t].[Ints] = @ints +"""); + } + + public override async Task Column_collection_inside_json_owned_entity() + { + await base.Column_collection_inside_json_owned_entity(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(JSON_QUERY([t].[Owned], '$.Strings')) AS [s]) = 2 +""", + // + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE JSON_VALUE([t].[Owned], '$.Strings[1]' RETURNING nvarchar(max)) = N'bar' +"""); + } + + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(""); + } + + public override async Task Constant_with_inferred_value_converter() + { + await base.Constant_with_inferred_value_converter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[PropertyWithValueConverter] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (8)) AS [v]([Value]) + WHERE [v].[Value] = [t].[PropertyWithValueConverter]) = 1 +"""); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -2537,6 +2851,31 @@ public override async Task Project_inline_collection_with_Concat() AssertSql(); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT [t].[Ints] +FROM [TestEntityWithOwned] AS [t] +"""); + } + + public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); + + AssertSql( + """ +SELECT [b].[Id], [b].[Discriminator], [b].[Ints] +FROM [BaseType] AS [b] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON([b].[Ints]) AS [i]) +"""); + } + public override async Task Nested_contains_with_Lists_and_no_inferred_type_mapping() { await base.Nested_contains_with_Lists_and_no_inferred_type_mapping(); @@ -2596,6 +2935,15 @@ SELECT COUNT(*) """); } + protected override DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); + + return optionsBuilder; + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index 4aae19d1fe0..f851a04f375 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -1,8 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.EntityFrameworkCore.SqlServer.Internal; + namespace Microsoft.EntityFrameworkCore.Query; +#nullable disable +using static System.Linq.Expressions.Expression; + public class PrimitiveCollectionsQuerySqlServerTest : PrimitiveCollectionsQueryRelationalTestBase< PrimitiveCollectionsQuerySqlServerTest.PrimitiveCollectionsQuerySqlServerFixture> { @@ -494,6 +499,21 @@ FROM OPENJSON(@p) WITH ([value] int '$') AS [p0] """); } + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (2), (3)) AS [v]([Value]) + WHERE [v].[Value] > [t].[Id]) = 1 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -1056,6 +1076,245 @@ public override async Task Parameter_collection_of_ints_Contains_int_with_huge_n Assert.Contains("OPENJSON(@ints) WITH ([Value] int '$')", Fixture.TestSqlLoggerFactory.SqlStatements[1], StringComparison.Ordinal); } + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ints='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(2 AS int)), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ids='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ints='[2,999]' (Size = 4000) + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + } + + public override async Task Parameter_collection_Contains_parameter_bucketization() + { + await base.Parameter_collection_Contains_parameter_bucketization(); + + AssertSql( + """ +@ints1='2' +@ints2='999' +@ints3='2' +@ints4='2' +@ints5='2' +@ints6='2' +@ints7='2' +@ints8='2' +@ints9='2' +@ints10='2' +@ints11='2' +@ints12='2' +@ints13='2' +@ints14='2' +@ints15='2' +@ints16='2' +@ints17='2' +@ints18='2' +@ints19='2' +@ints20='2' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) +"""); + } + public override async Task Static_readonly_collection_List_of_ints_Contains_int() { await base.Static_readonly_collection_List_of_ints_Contains_int(); @@ -1223,6 +1482,66 @@ await context.Database.SqlQuery($"SELECT [Bools] AS [Value] FROM [Primit .SingleAsync()); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' (Size = 4000) + +SELECT TOP(2) [t].[Id], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE [t].[Ints] = @ints +"""); + } + + public override async Task Column_collection_inside_json_owned_entity() + { + await base.Column_collection_inside_json_owned_entity(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(JSON_QUERY([t].[Owned], '$.Strings')) AS [s]) = 2 +""", + // + """ +SELECT TOP(2) [t].[Id], [t].[Owned] +FROM [TestOwner] AS [t] +WHERE JSON_VALUE([t].[Owned], '$.Strings[1]') = N'bar' +"""); + } + + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(""); + } + + public override async Task Constant_with_inferred_value_converter() + { + await base.Constant_with_inferred_value_converter(); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[PropertyWithValueConverter] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM (VALUES (CAST(1 AS int)), (8)) AS [v]([Value]) + WHERE [v].[Value] = [t].[PropertyWithValueConverter]) = 1 +"""); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -2400,6 +2719,31 @@ public override async Task Project_inline_collection_with_Concat() AssertSql(); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT [t].[Ints] +FROM [TestEntityWithOwned] AS [t] +"""); + } + + public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); + + AssertSql( + """ +SELECT [b].[Id], [b].[Discriminator], [b].[Ints] +FROM [BaseType] AS [b] +WHERE EXISTS ( + SELECT 1 + FROM OPENJSON([b].[Ints]) AS [i]) +"""); + } + public override async Task Nested_contains_with_Lists_and_no_inferred_type_mapping() { await base.Nested_contains_with_Lists_and_no_inferred_type_mapping(); @@ -2613,6 +2957,540 @@ public virtual async Task Parameter_collection_with_null_value_Contains_null_220 // No SQL assertion as the SQL is huge } + [ConditionalFact] + public virtual async Task Ordered_array_of_string() + { + await TestOrderedArray("a", "b"); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT [s].[value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = N'a') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_int() + { + await TestOrderedArray(1, 2); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS int) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = 1) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_long() + { + await TestOrderedArray(1L, 2L); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS bigint) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = CAST(1 AS bigint)) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_short() + { + await TestOrderedArray((short)1, (short)2); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS smallint) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = CAST(1 AS smallint)) = 2 +"""); + } + + // On relational databases, byte[] gets mapped to a special binary data type, which isn't queryable as a regular primitive collection. + [ConditionalFact] + public virtual async Task Ordered_array_of_byte() + => await AssertTranslationFailed(() => TestOrderedArray((byte)1, (byte)2)); + + [ConditionalFact] + public virtual async Task Ordered_array_of_double() + { + await TestOrderedArray(1d, 2d); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS float) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = 1.0E0) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_float() + { + await TestOrderedArray(1f, 2f); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS real) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = CAST(1 AS real)) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_decimal() + { + await TestOrderedArray(1m, 2m); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS decimal(18,2)) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = 1.0) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_DateTime() + { + await TestOrderedArray(new DateTime(2023, 1, 1, 12, 30, 0), new DateTime(2023, 1, 2, 12, 30, 0)); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS datetime2) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = '2023-01-01T12:30:00.0000000') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_DateOnly() + { + await TestOrderedArray(new DateOnly(2023, 1, 1), new DateOnly(2023, 1, 2)); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS date) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = '2023-01-01') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_TimeOnly() + { + await TestOrderedArray(new TimeOnly(12, 30, 0), new TimeOnly(12, 30, 1)); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS time) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = '12:30:00') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_DateTimeOffset() + { + await TestOrderedArray( + new DateTimeOffset(2023, 1, 1, 12, 30, 0, TimeSpan.FromHours(2)), + new DateTimeOffset(2023, 1, 2, 12, 30, 0, TimeSpan.FromHours(2))); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS datetimeoffset) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = '2023-01-01T12:30:00.0000000+02:00') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_bool() + { + await TestOrderedArray(true, false); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS bit) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = CAST(1 AS bit)) = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_guid() + { + await TestOrderedArray( + new Guid("dc8c903d-d655-4144-a0fd-358099d40ae1"), + new Guid("008719a5-1999-4798-9cf3-92a78ffa94a2")); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS uniqueidentifier) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = 'dc8c903d-d655-4144-a0fd-358099d40ae1') = 2 +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_byte_array() + { + var exception = await Assert.ThrowsAsync(() => TestOrderedArray([1, 2], new byte[] { 3, 4 })); + + Assert.Equal(SqlServerStrings.QueryingOrderedBinaryJsonCollectionsNotSupported, exception.Message); + } + + [ConditionalFact] + public virtual async Task Ordered_array_of_enum() + { + await TestOrderedArray(OrderedTestEnum.Label1, OrderedTestEnum.Label2); + + AssertSql( + """ +SELECT TOP(2) [t].[Id], [t].[Ints], [t].[SomeArray] +FROM [TestEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM ( + SELECT CAST([s].[value] AS int) AS [value] + FROM OPENJSON([t].[SomeArray]) AS [s] + ORDER BY CAST([s].[key] AS int) + OFFSET 1 ROWS + ) AS [s0] + WHERE [s0].[value] = 0) = 2 +"""); + } + + private enum OrderedTestEnum { Label1, Label2 } + + private async Task TestOrderedArray( + TElement value1, + TElement value2, + Action onModelCreating = null) + { + var arrayClrType = typeof(TElement).MakeArrayType(); + + var contextFactory = await InitializeNonSharedTest( + onModelCreating: onModelCreating ?? (mb => mb.Entity().Property(arrayClrType, "SomeArray")), + seed: context => + { + var instance1 = new TestEntity { Id = 1 }; + context.Add(instance1); + var array1 = new TElement[3]; + array1.SetValue(value1, 0); // We have an extra copy of the first value which we'll Skip, to preserve the ordering + array1.SetValue(value1, 1); + array1.SetValue(value1, 2); + context.Entry(instance1).Property("SomeArray").CurrentValue = array1; + + var instance2 = new TestEntity { Id = 2 }; + context.Add(instance2); + var array2 = new TElement[3]; + array2.SetValue(value1, 0); + array2.SetValue(value1, 1); + array2.SetValue(value2, 2); + context.Entry(instance2).Property("SomeArray").CurrentValue = array2; + + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + var entityParam = Parameter(typeof(TestEntity), "m"); + var efPropertyCall = Call( + typeof(EF).GetMethod(nameof(EF.Property), BindingFlags.Public | BindingFlags.Static)!.MakeGenericMethod(arrayClrType), + entityParam, + Constant("SomeArray")); + + var elementParam = Parameter(typeof(TElement), "a"); + var predicate = Lambda>( + Equal( + Call( + CountWithPredicateMethod.MakeGenericMethod(typeof(TElement)), + Call( + SkipMethod.MakeGenericMethod(typeof(TElement)), + efPropertyCall, + Constant(1)), + Lambda(Equal(elementParam, Constant(value1)), elementParam)), + Constant(2)), + entityParam); + + // context.Set().SingleAsync(m => EF.Property(m, "SomeArray").Skip(1).Count(a => a == ) == 2) + var result = await context.Set().SingleAsync(predicate); + Assert.Equal(1, result.Id); + } + + private static readonly MethodInfo CountWithPredicateMethod + = typeof(Enumerable).GetRuntimeMethods().Single(m => m.Name == nameof(Enumerable.Count) && m.GetParameters().Length == 2); + + private static readonly MethodInfo SkipMethod + = typeof(Enumerable).GetRuntimeMethods().Single(m => m.Name == nameof(Enumerable.Skip) && m.GetParameters().Length == 2); + + [ConditionalFact] + public virtual async Task Same_parameter_with_different_type_mappings() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => + { + b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"); + b.Property(typeof(DateTime), "DateTime2").HasColumnType("datetime2"); + })); + + await using var context = contextFactory.CreateDbContext(); + + var dateTimes = new[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00) }; + + _ = await context.Set() + .Where(m => + dateTimes.Contains(EF.Property(m, "DateTime")) + && dateTimes.Contains(EF.Property(m, "DateTime2"))) + .ToArrayAsync(); + + AssertSql( + """ +@dateTimes1='2020-01-01T12:30:00.0000000' (DbType = DateTime) +@dateTimes2='2020-01-02T12:30:00.0000000' (DbType = DateTime) +@dateTimes3='2020-01-01T12:30:00.0000000' +@dateTimes4='2020-01-02T12:30:00.0000000' + +SELECT [t].[Id], [t].[DateTime], [t].[DateTime2], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE [t].[DateTime] IN (@dateTimes1, @dateTimes2) AND [t].[DateTime2] IN (@dateTimes3, @dateTimes4) +"""); + } + + [ConditionalFact] + public virtual async Task Same_collection_with_default_type_mapping_and_uninferrable_context() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => b.Property(typeof(DateTime), "DateTime"))); + + await using var context = contextFactory.CreateDbContext(); + + var dateTimes = new DateTime?[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00), null }; + + _ = await context.Set() + .Where(m => dateTimes.Any(d => d == EF.Property(m, "DateTime") && d != null)) + .ToArrayAsync(); + + AssertSql( + """ +@dateTimes1='2020-01-01T12:30:00.0000000' +@dateTimes2='2020-01-02T12:30:00.0000000' +@dateTimes3=NULL (DbType = DateTime2) + +SELECT [t].[Id], [t].[DateTime], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE EXISTS ( + SELECT 1 + FROM (VALUES (@dateTimes1), (@dateTimes2), (@dateTimes3)) AS [d]([Value]) + WHERE [d].[Value] = [t].[DateTime] AND [d].[Value] IS NOT NULL) +"""); + } + + [ConditionalFact] + public virtual async Task Same_collection_with_non_default_type_mapping_and_uninferrable_context() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"))); + + await using var context = contextFactory.CreateDbContext(); + + var dateTimes = new DateTime?[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00), null }; + + var exception = await Assert.ThrowsAsync(() => context.Set() + .Where(m => dateTimes.Any(d => d == EF.Property(m, "DateTime") && d != null)) + .ToArrayAsync()); + Assert.Equal(RelationalStrings.ConflictingTypeMappingsInferredForColumn("Value"), exception.Message); + } + + [ConditionalFact] + public virtual async Task Same_collection_with_conflicting_type_mappings_not_supported() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => + { + b.Property(typeof(DateTime), "DateTime").HasColumnType("datetime"); + b.Property(typeof(DateTime), "DateTime2").HasColumnType("datetime2"); + })); + + await using var context = contextFactory.CreateDbContext(); + + var dateTimes = new[] { new DateTime(2020, 1, 1, 12, 30, 00), new DateTime(2020, 1, 2, 12, 30, 00) }; + + var exception = await Assert.ThrowsAsync(() => context.Set() + .Where(m => dateTimes + .Any(d => d == EF.Property(m, "DateTime") && d == EF.Property(m, "DateTime2"))) + .ToArrayAsync()); + Assert.Equal(RelationalStrings.ConflictingTypeMappingsInferredForColumn("Value"), exception.Message); + } + + [ConditionalFact] + public virtual async Task Infer_inline_collection_type_mapping() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(b => b.Property("DateTime").HasColumnType("datetime"))); + + await using var context = contextFactory.CreateDbContext(); + + _ = await context.Set() + .Where(b => new[] { new DateTime(2020, 1, 1), EF.Property(b, "DateTime") }[0] == new DateTime(2020, 1, 1)) + .ToArrayAsync(); + + AssertSql( + """ +SELECT [t].[Id], [t].[DateTime], [t].[Ints] +FROM [TestEntity] AS [t] +WHERE ( + SELECT [v].[Value] + FROM (VALUES (0, CAST('2020-01-01T00:00:00.000' AS datetime)), (1, [t].[DateTime])) AS [v]([_ord], [Value]) + ORDER BY [v].[_ord] + OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) = '2020-01-01T00:00:00.000' +"""); + } + + [ConditionalFact] + public virtual async Task Ordered_collection_with_split_query() + { + var contextFactory = await InitializeNonSharedTest( + onModelCreating: mb => mb.Entity(), + seed: context => + { + context.Add(new Context32976.Principal { Ints = [2, 3, 4] }); + return context.SaveChangesAsync(); + }); + + await using var context = contextFactory.CreateDbContext(); + + _ = await context.Set() + .Where(p => p.Ints.Skip(1).Contains(3)) + .Include(p => p.Dependents) + .AsSplitQuery() + .SingleAsync(); + } + + public class Context32976(DbContextOptions options) : DbContext(options) + { + public class Principal + { + public int Id { get; set; } + public List Ints { get; set; } + public List Dependents { get; set; } + } + + public class Dependent + { + public int Id { get; set; } + public Principal Principal { get; set; } + } + } + [ConditionalFact] public virtual async Task Parameter_collection_of_ints_Contains_int_2071_values() { @@ -2647,6 +3525,15 @@ public virtual Task Parameter_collection_Count_parameters_limit(int count) return AssertQuery(ss => ss.Set().Where(c => ids.Count(i => i > c.Id) > 0)); } + protected override DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode) + { + new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); + + return optionsBuilder; + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyCollectionTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyCollectionTypeTest.cs index 04547d2678b..bd39833fb36 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyCollectionTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyCollectionTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('GEOMETRYCOLLECTION (POINT (-122.35 47.62), LINESTRIN """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyLineStringTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyLineStringTypeTest.cs index c0d2508afdc..84f3a426f03 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyLineStringTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyLineStringTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('LINESTRING (-122.34877 47.6233355, -122.3308366 47.5 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiLineStringTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiLineStringTypeTest.cs index dfa3bf7e3eb..e81f7fef5ee 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiLineStringTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiLineStringTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('MULTILINESTRING ((-122.35 47.62, -122.345 47.615), ( """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPointTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPointTypeTest.cs index 0548b7c5e69..18625cd14f2 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPointTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPointTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('MULTIPOINT ((-122.35 47.62), (-122.345 47.615))') = """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPolygonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPolygonTypeTest.cs index 74a024455cb..f07b3326ee7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPolygonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyMultiPolygonTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('MULTIPOLYGON (((-122.35 47.62, -122.35 47.615, -122. """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPointTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPointTypeTest.cs index 494ed45082f..591bd268852 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPointTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPointTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('POINT (-122.34877 47.6233355)') = CAST(1 AS bit) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPolygonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPolygonTypeTest.cs index 3eb550ae4c1..e212a734215 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPolygonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geography/SqlServerGeographyPolygonTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('POLYGON ((-122.35 47.62, -122.35 47.61, -122.34 47.6 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryCollectionTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryCollectionTypeTest.cs index a0a6ad6ffed..8f33d2fd69a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryCollectionTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryCollectionTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (2 2, 3 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryLineStringTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryLineStringTypeTest.cs index 63d508b7bf3..aa03597dce2 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryLineStringTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryLineStringTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('LINESTRING (10 20, 15 25)') = CAST(1 AS bit) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiLineStringTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiLineStringTypeTest.cs index aa4c117324e..1c14e65b325 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiLineStringTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiLineStringTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))') = CAST(1 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPointTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPointTypeTest.cs index ec05e5cb3d1..73ad92f7866 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPointTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPointTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('MULTIPOINT ((5 5), (10 10))') = CAST(1 AS bit) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPolygonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPolygonTypeTest.cs index 5eec5dd40bb..6d469041f56 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPolygonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryMultiPolygonTypeTest.cs @@ -36,6 +36,11 @@ WHERE [t].[Value].STEquals('MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)), ((10 10, """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPointTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPointTypeTest.cs index 1498b8d86a1..aca36803649 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPointTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPointTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('POINT (10 20)') = CAST(1 AS bit) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPolygonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPolygonTypeTest.cs index abb3df919e4..5604bc978a6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPolygonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Geometry/SqlServerGeometryPolygonTypeTest.cs @@ -34,6 +34,11 @@ WHERE [t].[Value].STEquals('POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))') = CAST(1 A """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerBoolTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerBoolTypeTest.cs index c3e485dc929..526afec5e4f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerBoolTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerBoolTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='True' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = CAST(1 AS bit) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='True' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] bit '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerByteArrayTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerByteArrayTypeTest.cs index a6d2e1be725..a5abf44d4a9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerByteArrayTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerByteArrayTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='0x010203' (Size = 8000) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,16 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = 0x010203 """); } + // byte[].Equals() does reference equality, so the base test doesn't work for byte arrays + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerGuidTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerGuidTypeTest.cs index 5e43a457cbf..37cd7611ee0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerGuidTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerGuidTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='8f7331d6-cde9-44fb-8611-81fff686f280' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '8f7331d6-cde9-44fb-8611-81fff686f280' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='8f7331d6-cde9-44fb-8611-81fff686f280' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] uniqueidentifier '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerStringTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerStringTypeTest.cs index 461f9267bd7..de7c4ad1a55 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerStringTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Miscellaneous/SqlServerStringTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='foo' (Size = 4000) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = N'foo' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='foo' (Size = 4000) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] nvarchar(max) '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerByteTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerByteTypeTest.cs index 58a4634933a..ae2af082c14 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerByteTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerByteTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='0' (Size = 1) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = CAST(0 AS tinyint) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='0' (Size = 1) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] tinyint '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDecimalTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDecimalTypeTest.cs index 9a1c8eac6c5..3191fc55837 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDecimalTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDecimalTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='30.5' (Precision = 18) (Scale = 2) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = 30.5 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='30.5' (Precision = 18) (Scale = 2) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] decimal(18,2) '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDoubleTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDoubleTypeTest.cs index 5712590e456..4d701563294 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDoubleTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerDoubleTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='30.5' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = 30.5E0 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='30.5' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] float '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerFloatTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerFloatTypeTest.cs index d56dc7c4b7c..710f12b69a3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerFloatTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerFloatTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='30.5' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = CAST(30.5 AS real) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='30.5' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] real '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerIntTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerIntTypeTest.cs index cba511ae2e7..41f21ca407c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerIntTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerIntTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='-2147483648' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = -2147483648 """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='-2147483648' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] int '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerLongTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerLongTypeTest.cs index 4a3be659762..e14e9de07f1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerLongTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerLongTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='-9223372036854775808' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = CAST(-9223372036854775808 AS bigint) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='-9223372036854775808' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] bigint '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerShortTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerShortTypeTest.cs index 1c8f72791cf..7c1d778ef74 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerShortTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Numeric/SqlServerShortTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='-32768' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = CAST(-32768 AS smallint) """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='-32768' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] smallint '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/SqlServerSpatialTypeTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/Types/SqlServerSpatialTypeTestBase.cs index 63703e78d95..bc8fc7e03fe 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/SqlServerSpatialTypeTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/SqlServerSpatialTypeTestBase.cs @@ -58,10 +58,24 @@ public override async Task Query_property_within_json() Assert.Equal(Fixture.Value, result.JsonContainer.Value, Fixture.Comparer); } + // Spatial types aren't supported as primitive collections + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public abstract class SqlServerSpatialTypeFixture : SqlServerTypeFixture { public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).UseSqlServer(o => o.UseNetTopologySuite()); + => base.AddOptions(builder) + .UseSqlServer(o => o.UseNetTopologySuite()) + .ConfigureWarnings(w => w.Ignore(CoreEventId.MappedPropertyIgnoredWarning)); + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + // Spatial types aren't supported as primitive collections + modelBuilder.Entity>().Ignore(e => e.ArrayValue); + } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateOnlyTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateOnlyTypeTest.cs index 49b3105d48b..1f4d8c6850f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateOnlyTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateOnlyTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='01/05/2020' (DbType = Date) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '2020-01-05' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='01/05/2020' (DbType = Date) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] date '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTime2TypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTime2TypeTest.cs index 3b8f6949b2b..780698d5c05 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTime2TypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTime2TypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='2020-01-05T12:30:45.0000000' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '2020-01-05T12:30:45.0000000' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='2020-01-05T12:30:45.0000000' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] datetime2 '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeOffsetTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeOffsetTypeTest.cs index 70c80ab2082..8382454ca32 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeOffsetTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeOffsetTypeTest.cs @@ -16,7 +16,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='2020-01-05T12:30:45.0000000+02:00' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -28,12 +28,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '2020-01-05T12:30:45.0000000+02:00' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='2020-01-05T12:30:45.0000000+02:00' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] datetimeoffset '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeTypeTest.cs index 2f9aef2537a..d3b4f2707ff 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerDateTimeTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='2020-01-05T12:30:45.0000000' (DbType = DateTime) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '2020-01-05T12:30:45.000' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='2020-01-05T12:30:45.0000000' (DbType = DateTime) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] datetime '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeOnlyTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeOnlyTypeTest.cs index 0c65dbcbef5..3f74e450b67 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeOnlyTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeOnlyTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='12:30' (DbType = Time) -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '12:30:45' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='12:30' (DbType = Time) + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] time '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeSpanTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeSpanTypeTest.cs index b2ae8e44dfc..cbbf85edc4b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeSpanTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Types/Temporal/SqlServerTimeSpanTypeTest.cs @@ -14,7 +14,7 @@ public override async Task Equality_in_query_with_parameter() """ @Fixture_Value='12:30:45' -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = @Fixture_Value """); @@ -26,12 +26,29 @@ public override async Task Equality_in_query_with_constant() AssertSql( """ -SELECT TOP(2) [t].[Id], [t].[OtherValue], [t].[Value] +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] FROM [TypeEntity] AS [t] WHERE [t].[Value] = '12:30:45' """); } + public override async Task Primitive_collection_in_query() + { + await base.Primitive_collection_in_query(); + + AssertSql( + """ +@value='12:30:45' + +SELECT TOP(2) [t].[Id], [t].[ArrayValue], [t].[OtherValue], [t].[Value] +FROM [TypeEntity] AS [t] +WHERE ( + SELECT COUNT(*) + FROM OPENJSON([t].[ArrayValue]) WITH ([value] time '$') AS [a] + WHERE [a].[value] = @value) = 2 +"""); + } + public override async Task SaveChanges() { await base.SaveChanges(); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs deleted file mode 100644 index 0979106dedd..00000000000 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs +++ /dev/null @@ -1,576 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Query; - -#nullable disable - -public class NonSharedPrimitiveCollectionsQuerySqliteTest(NonSharedFixture fixture) - : NonSharedPrimitiveCollectionsQueryRelationalTestBase(fixture) -{ - protected override DbContextOptionsBuilder SetParameterizedCollectionMode( - DbContextOptionsBuilder optionsBuilder, - ParameterTranslationMode parameterizedCollectionMode) - { - new SqliteDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); - - return optionsBuilder; - } - - #region Support for specific element types - - public override async Task Array_of_int() - { - await base.Array_of_int(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 1) = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_long() - { - await base.Array_of_long(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 1) = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_short() - { - await base.Array_of_short(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 1) = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_double() - { - await base.Array_of_double(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 1.0) = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_float() - { - await base.Array_of_float(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 1) = 2 -LIMIT 2 -"""); - } - - // The JSON representation for decimal is e.g. 1 (JSON int), whereas our literal representation is "1.0" (string). - // We can cast the 1 to TEXT, but we'd still get "1" not "1.0". - public override async Task Array_of_decimal() - { - await base.Array_of_decimal(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '1.0') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime() - { - await base.Array_of_DateTime(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '2023-01-01 12:30:00') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime_with_milliseconds() - { - await base.Array_of_DateTime_with_milliseconds(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '2023-01-01 12:30:00.123') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_DateTime_with_microseconds() - { - await base.Array_of_DateTime_with_microseconds(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '2023-01-01 12:30:00.123456') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_DateOnly() - { - await base.Array_of_DateOnly(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '2023-01-01') = 2 -LIMIT 2 -"""); - } - - [ConditionalFact(Skip = "Issue #30730: TODO: SQLite is not matching elements here.")] - public override async Task Array_of_TimeOnly() - { - await base.Array_of_TimeOnly(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '12:30:00') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_milliseconds() - { - await base.Array_of_TimeOnly_with_milliseconds(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '12:30:00.1230000') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_TimeOnly_with_microseconds() - { - await base.Array_of_TimeOnly_with_microseconds(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '12:30:00.1234560') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_DateTimeOffset() - { - await base.Array_of_DateTimeOffset(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = '2023-01-01 12:30:00+02:00') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_bool() - { - await base.Array_of_bool(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value") = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_Guid() - { - await base.Array_of_Guid(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 'DC8C903D-D655-4144-A0FD-358099D40AE1') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_byte_array() - { - await base.Array_of_byte_array(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE unhex("s"."value") = X'0102') = 2 -LIMIT 2 -"""); - } - - public override async Task Array_of_enum() - { - await base.Array_of_enum(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Ints", "t"."SomeArray" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each("t"."SomeArray") AS "s" - WHERE "s"."value" = 0) = 2 -LIMIT 2 -"""); - } - - #endregion Support for specific element types - - public override async Task Column_collection_inside_json_owned_entity() - { - await base.Column_collection_inside_json_owned_entity(); - - AssertSql( - """ -SELECT "t"."Id", "t"."Owned" -FROM "TestOwner" AS "t" -WHERE json_array_length("t"."Owned" ->> 'Strings') = 2 -LIMIT 2 -""", - // - """ -SELECT "t"."Id", "t"."Owned" -FROM "TestOwner" AS "t" -WHERE "t"."Owned" ->> '$.Strings[1]' = 'bar' -LIMIT 2 -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); - - switch (mode) - { - case ParameterTranslationMode.Constant: - { - AssertSql( - """ -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM (SELECT CAST(2 AS INTEGER) AS "Value" UNION ALL VALUES (999)) AS "i" - WHERE "i"."Value" > "t"."Id") = 1 -"""); - break; - } - - case ParameterTranslationMode.Parameter: - { - AssertSql( - """ -@ids='[2,999]' (Size = 7) - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each(@ids) AS "i" - WHERE "i"."value" > "t"."Id") = 1 -"""); - break; - } - - case ParameterTranslationMode.MultipleParameters: - { - AssertSql( - """ -@ids1='2' -@ids2='999' - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM (SELECT @ids1 AS "Value" UNION ALL VALUES (@ids2)) AS "i" - WHERE "i"."Value" > "t"."Id") = 1 -"""); - break; - } - - default: - throw new NotImplementedException(); - } - } - - public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode(mode); - - switch (mode) - { - case ParameterTranslationMode.Constant: - { - AssertSql( - """ -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (2, 999) -"""); - break; - } - - case ParameterTranslationMode.Parameter: - { - AssertSql( - """ -@ints='[2,999]' (Size = 7) - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN ( - SELECT "i"."value" - FROM json_each(@ints) AS "i" -) -"""); - break; - } - - case ParameterTranslationMode.MultipleParameters: - { - AssertSql( - """ -@ints1='2' -@ints2='999' - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (@ints1, @ints2) -"""); - break; - } - - default: - throw new NotImplementedException(); - } - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); - - AssertSql( - """ -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM (SELECT CAST(2 AS INTEGER) AS "Value" UNION ALL VALUES (999)) AS "i" - WHERE "i"."Value" > "t"."Id") = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); - - AssertSql( - """ -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (2, 999) -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( - ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); - - AssertSql( - """ -@ids='[2,999]' (Size = 7) - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM json_each(@ids) AS "i" - WHERE "i"."value" > "t"."Id") = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); - - AssertSql( - """ -@ints='[2,999]' (Size = 7) - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN ( - SELECT "i"."value" - FROM json_each(@ints) AS "i" -) -"""); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( - ParameterTranslationMode mode) - { - await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); - - AssertSql( - """ -@ids1='2' -@ids2='999' - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE ( - SELECT COUNT(*) - FROM (SELECT @ids1 AS "Value" UNION ALL VALUES (@ids2)) AS "i" - WHERE "i"."Value" > "t"."Id") = 1 -"""); - } - - public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) - { - await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); - - AssertSql( - """ -@ints1='2' -@ints2='999' - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (@ints1, @ints2) -"""); - } - - public override async Task Parameter_collection_Contains_parameter_bucketization() - { - await base.Parameter_collection_Contains_parameter_bucketization(); - - AssertSql( - """ -@ints1='2' -@ints2='999' -@ints3='2' -@ints4='2' -@ints5='2' -@ints6='2' -@ints7='2' -@ints8='2' -@ints9='2' -@ints10='2' -@ints11='2' -@ints12='2' -@ints13='2' -@ints14='2' -@ints15='2' -@ints16='2' -@ints17='2' -@ints18='2' -@ints19='2' -@ints20='2' - -SELECT "t"."Id" -FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) -"""); - } - - protected override ITestStoreFactory TestStoreFactory - => SqliteTestStoreFactory.Instance; -} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 657f5effcd7..2701a648b2e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -482,6 +482,22 @@ FROM json_each(@p) AS "p0" """); } + public override async Task Inline_collection_in_query_filter() + { + await base.Inline_collection_in_query_filter(); + + AssertSql( + """ +SELECT "t"."Id", "t"."Ints" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT CAST(1 AS INTEGER) AS "Value" UNION ALL VALUES (2), (3)) AS "v" + WHERE "v"."Value" > "t"."Id") = 1 +LIMIT 2 +"""); + } + public override async Task Parameter_collection_Count() { await base.Parameter_collection_Count(); @@ -996,6 +1012,245 @@ public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_ public override Task Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_mixed_parameters_constants() => base.Parameter_collection_of_ints_Contains_int_with_huge_number_of_values_over_5_operations_mixed_parameters_constants(); + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT CAST(2 AS INTEGER) AS "Value" UNION ALL VALUES (999)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM json_each(@ids) AS "i" + WHERE "i"."value" > "t"."Id") = 1 +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT @ids1 AS "Value" UNION ALL VALUES (@ids2)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ints='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN ( + SELECT "i"."value" + FROM json_each(@ints) AS "i" +) +"""); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT CAST(2 AS INTEGER) AS "Value" UNION ALL VALUES (999)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); + + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (2, 999) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ids='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM json_each(@ids) AS "i" + WHERE "i"."value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); + + AssertSql( + """ +@ints='[2,999]' (Size = 7) + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN ( + SELECT "i"."value" + FROM json_each(@ints) AS "i" +) +"""); + } + + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters( + ParameterTranslationMode mode) + { + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ids1='2' +@ids2='999' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT @ids1 AS "Value" UNION ALL VALUES (@ids2)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 +"""); + } + + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) + { + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); + + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (@ints1, @ints2) +"""); + } + + public override async Task Parameter_collection_Contains_parameter_bucketization() + { + await base.Parameter_collection_Contains_parameter_bucketization(); + + AssertSql( + """ +@ints1='2' +@ints2='999' +@ints3='2' +@ints4='2' +@ints5='2' +@ints6='2' +@ints7='2' +@ints8='2' +@ints9='2' +@ints10='2' +@ints11='2' +@ints12='2' +@ints13='2' +@ints14='2' +@ints15='2' +@ints16='2' +@ints17='2' +@ints18='2' +@ints19='2' +@ints20='2' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (@ints1, @ints2, @ints3, @ints4, @ints5, @ints6, @ints7, @ints8, @ints9, @ints10, @ints11, @ints12, @ints13, @ints14, @ints15, @ints16, @ints17, @ints18, @ints19, @ints20) +"""); + } + public override async Task Static_readonly_collection_List_of_ints_Contains_int() { await base.Static_readonly_collection_List_of_ints_Contains_int(); @@ -1152,6 +1407,41 @@ FROM json_each("p"."Bools") AS "b" """); } + public override async Task Column_with_custom_converter() + { + await base.Column_with_custom_converter(); + + AssertSql( + """ +@ints='1,2,3' (Size = 5) + +SELECT "t"."Id", "t"."Ints" +FROM "TestEntity" AS "t" +WHERE "t"."Ints" = @ints +LIMIT 2 +"""); + } + + public override async Task Column_collection_inside_json_owned_entity() + { + await base.Column_collection_inside_json_owned_entity(); + + AssertSql( + """ +SELECT "t"."Id", "t"."Owned" +FROM "TestOwner" AS "t" +WHERE json_array_length("t"."Owned" ->> 'Strings') = 2 +LIMIT 2 +""", + // + """ +SELECT "t"."Id", "t"."Owned" +FROM "TestOwner" AS "t" +WHERE "t"."Owned" ->> '$.Strings[1]' = 'bar' +LIMIT 2 +"""); + } + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -2408,6 +2698,15 @@ SELECT COUNT(*) """); } + protected override DbContextOptionsBuilder SetParameterizedCollectionMode( + DbContextOptionsBuilder optionsBuilder, + ParameterTranslationMode parameterizedCollectionMode) + { + new SqliteDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); + + return optionsBuilder; + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); diff --git a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs index 442772613a1..73e3d6d4edf 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteMiscellaneousTypeTest.cs @@ -47,6 +47,10 @@ public class SqliteByteArrayTypeTest(SqliteByteArrayTypeTest.ByteArrayTypeFixtur public override Task Query_property_within_json() => Assert.ThrowsAsync(() => base.Query_property_within_json()); + // byte[].Equals() does reference equality, so the base test doesn't work for byte arrays + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public override async Task ExecuteUpdate_within_json_to_nonjson_column() { // See #36688 for supporting this for Sqlite types other than string/numeric/bool diff --git a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs index d3655b6a938..c3cfd0ebc2a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Types/SqliteTemporalTypeTest.cs @@ -61,6 +61,10 @@ public class SqliteTimeOnlyTypeTest(SqliteTimeOnlyTypeTest.TimeTypeFixture fixtu public override Task Query_property_within_json() => Assert.ThrowsAsync(() => base.Query_property_within_json()); + // TODO: TimeOnly comparison within JSON primitive collections doesn't work on SQLite, see #36749. + public override Task Primitive_collection_in_query() + => Task.CompletedTask; + public override async Task ExecuteUpdate_within_json_to_nonjson_column() { // See #36688 for supporting this for Sqlite types other than string/numeric/bool From f3f87fbffa94a08bb76614ba1560afe0f41c5c27 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 13 Feb 2026 22:22:39 +0100 Subject: [PATCH 2/2] Make QueryTestBase extend NonSharedModelTestBase --- .../AdHocVectorSearchCosmosTest.cs | 8 +- .../AddHocFullTextSearchCosmosTest.cs | 20 +- .../CosmosSessionTokensTest.cs | 36 ++-- .../CosmosTriggersTest.cs | 12 +- .../EndToEndCosmosTest.cs | 54 ++--- .../JsonTypesCosmosTest.cs | 2 +- .../MaterializationInterceptionCosmosTest.cs | 2 +- .../Query/AdHocJsonQueryCosmosTest.cs | 4 +- .../AdHocMiscellaneousQueryCosmosTest.cs | 46 ++--- .../Scaffolding/CompiledModelCosmosTest.cs | 2 +- .../Update/CosmosBulkEndToEndTest.cs | 4 +- .../CosmosBulkEndToEndTestNoBatching.cs | 4 +- .../Update/CosmosBulkExecutionTest.cs | 16 +- .../JsonTypesInMemoryTest.cs | 2 +- ...MaterializationInterceptionInMemoryTest.cs | 6 +- .../AdHocAdvancedMappingsQueryInMemoryTest.cs | 2 +- .../Query/AdHocManyToManyQueryInMemoryTest.cs | 2 +- .../AdHocMiscellaneousQueryInMemoryTest.cs | 2 +- .../AdHocNavigationsQueryInMemoryTest.cs | 2 +- .../AdHocQueryFiltersQueryInMemoryTest.cs | 8 +- .../Query/OwnedEntityQueryInMemoryTest.cs | 14 +- .../Query/SharedTypeQueryInMemoryTest.cs | 6 +- .../Scaffolding/CompiledModelInMemoryTest.cs | 6 +- ...haredModelBulkUpdatesRelationalTestBase.cs | 30 +-- .../EntitySplittingTestBase.cs | 6 +- ...AdvancedMappingsQueryRelationalTestBase.cs | 12 +- ...AdHocComplexTypeQueryRelationalTestBase.cs | 12 +- .../Query/AdHocJsonQueryRelationalTestBase.cs | 20 +- ...HocMiscellaneousQueryRelationalTestBase.cs | 30 +-- ...AdHocNavigationsQueryRelationalTestBase.cs | 4 +- ...AdHocPrecompiledQueryRelationalTestBase.cs | 16 +- .../Query/AdHocQuerySplittingQueryTestBase.cs | 56 +++--- .../Query/EntitySplittingQueryTestBase.cs | 10 +- .../Query/OperatorsProceduralQueryTestBase.cs | 10 +- .../Query/OperatorsQueryTestBase.cs | 42 ++-- .../OwnedEntityQueryRelationalTestBase.cs | 50 ++--- .../SharedTypeQueryRelationalTestBase.cs | 14 +- .../Query/ToSqlQueryTestBase.cs | 6 +- .../CompiledModelRelationalTestBase.cs | 4 +- .../TPTTableSplittingTestBase.cs | 2 +- .../TableSplittingTestBase.cs | 14 +- .../Update/NonSharedModelUpdatesTestBase.cs | 10 +- .../Update/StoredProcedureUpdateTestBase.cs | 128 ++++++------ .../NonSharedModelBulkUpdatesTestBase.cs | 46 ++--- .../JsonTypesTestBase.cs | 4 +- .../MaterializationInterceptionTestBase.cs | 2 +- .../NonSharedModelTestBase.cs | 58 +++--- .../AdHocAdvancedMappingsQueryTestBase.cs | 70 +++---- .../Query/AdHocComplexTypeQueryTestBase.cs | 22 +- .../Query/AdHocJsonQueryTestBase.cs | 162 +++++++-------- .../Query/AdHocManyToManyQueryTestBase.cs | 14 +- .../Query/AdHocMiscellaneousQueryTestBase.cs | 188 +++++++++--------- .../Query/AdHocNavigationsQueryTestBase.cs | 104 +++++----- .../Query/AdHocQueryFiltersQueryTestBase.cs | 82 ++++---- .../Query/OwnedEntityQueryTestBase.cs | 50 ++--- .../PrimitiveCollectionsQueryTestBase.cs | 2 - .../Query/QueryFixtureBase.cs | 3 - .../Query/QueryTestBase.cs | 114 ++--------- .../Query/SharedTypeQueryTestBase.cs | 6 +- .../Scaffolding/CompiledModelTestBase.cs | 8 +- .../SharedStoreFixtureBase.cs | 9 +- .../SingletonInterceptorsTestBase.cs | 4 +- .../TestUtilities/NonSharedFixture.cs | 10 +- .../NonSharedModelBulkUpdatesSqlServerTest.cs | 2 +- .../EntitySplittingSqlServerTest.cs | 2 +- .../JsonTypesSqlServerTestBase.cs | 6 +- ...aterializationInterceptionSqlServerTest.cs | 2 +- ...AdHocAdvancedMappingsQuerySqlServerTest.cs | 2 +- .../AdHocComplexTypeQuerySqlServerTest.cs | 6 +- .../AdHocJsonQuerySqlServerJsonTypeTest.cs | 2 +- .../Query/AdHocJsonQuerySqlServerTestBase.cs | 14 +- .../AdHocManyToManyQuerySqlServerTest.cs | 2 +- .../AdHocMiscellaneousQuerySqlServerTest.cs | 116 +++++------ .../AdHocNavigationsQuerySqlServerTest.cs | 6 +- .../AdHocPrecompiledQuerySqlServerTest.cs | 6 +- .../AdHocQueryFiltersQuerySqlServerTest.cs | 10 +- .../AdHocQuerySplittingQuerySqlServerTest.cs | 10 +- .../EntitySplittingQuerySqlServerTest.cs | 2 +- .../Query/OperatorsProceduralSqlServerTest.cs | 2 +- .../Query/OperatorsQuerySqlServerTest.cs | 18 +- .../Query/OwnedEntityQuerySqlServerTest.cs | 16 +- .../Query/SharedTypeQuerySqlServerTest.cs | 2 +- .../Query/TemporalTableSqlServerTest.cs | 52 ++--- .../Query/ToSqlQuerySqlServerTest.cs | 2 +- .../Scaffolding/CompiledModelSqlServerTest.cs | 6 +- .../TPTTableSplittingSqlServerTest.cs | 2 +- .../TableSplittingSqlServerTest.cs | 2 +- .../NonSharedModelUpdatesSqlServerTest.cs | 6 +- .../StoredProcedureUpdateSqlServerTest.cs | 2 +- .../NonSharedModelBulkUpdatesSqliteTest.cs | 6 +- .../EntitySplittingSqliteTest.cs | 2 +- .../JsonTypesSqliteTest.cs | 6 +- .../MaterializationInterceptionSqliteTest.cs | 2 +- .../AdHocAdvancedMappingsQuerySqliteTest.cs | 2 +- .../Query/AdHocComplexTypeQuerySqliteTest.cs | 2 +- .../Query/AdHocJsonQuerySqliteTest.cs | 2 +- .../Query/AdHocManyToManyQuerySqliteTest.cs | 2 +- .../AdHocMiscellaneousQuerySqliteTest.cs | 2 +- .../Query/AdHocNavigationsQuerySqliteTest.cs | 2 +- .../Query/AdHocPrecompiledQuerySqliteTest.cs | 2 +- .../Query/AdHocQueryFiltersQuerySqliteTest.cs | 2 +- .../AdHocQuerySplittingQuerySqliteTest.cs | 2 +- .../Query/EntitySplittingQuerySqliteTest.cs | 2 +- .../Query/OperatorsProceduralSqliteTest.cs | 2 +- .../Query/OperatorsQuerySqliteTest.cs | 2 +- .../Query/OwnedEntityQuerySqliteTest.cs | 6 +- .../PrimitiveCollectionsQuerySqliteTest.cs | 50 +++++ .../Query/SharedTypeQuerySqliteTest.cs | 2 +- .../Query/ToSqlQuerySqliteTest.cs | 2 +- .../Scaffolding/CompiledModelSqliteTest.cs | 6 +- .../TPTTableSplittingSqliteTest.cs | 2 +- .../TableSplittingSqliteTest.cs | 2 +- .../Update/NonSharedModelUpdatesSqliteTest.cs | 2 +- 113 files changed, 1025 insertions(+), 1079 deletions(-) diff --git a/test/EFCore.Cosmos.FunctionalTests/AdHocVectorSearchCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/AdHocVectorSearchCosmosTest.cs index b82a6aa444f..5da07a196b5 100644 --- a/test/EFCore.Cosmos.FunctionalTests/AdHocVectorSearchCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/AdHocVectorSearchCosmosTest.cs @@ -9,10 +9,10 @@ namespace Microsoft.EntityFrameworkCore; [CosmosCondition(CosmosCondition.DoesNotUseTokenCredential)] public class AdHocVectorSearchCosmosTest(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocVectorSearchTests"; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; #region CompositeVectorIndex @@ -20,7 +20,7 @@ protected override ITestStoreFactory TestStoreFactory [ConditionalFact] public async Task Validate_composite_vector_index_throws() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( CosmosStrings.CompositeVectorIndex( @@ -60,7 +60,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public async Task Validate_vector_property_on_collection_navigation_container_creation() { var message = - (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( CosmosStrings.CreatingContainerWithFullTextOrVectorOnCollectionNotSupported("/Collection"), diff --git a/test/EFCore.Cosmos.FunctionalTests/AddHocFullTextSearchCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/AddHocFullTextSearchCosmosTest.cs index b7154eac46a..1d7dc6742a0 100644 --- a/test/EFCore.Cosmos.FunctionalTests/AddHocFullTextSearchCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/AddHocFullTextSearchCosmosTest.cs @@ -9,10 +9,10 @@ namespace Microsoft.EntityFrameworkCore; [CosmosCondition(CosmosCondition.DoesNotUseTokenCredential)] public class AdHocFullTextSearchCosmosTest(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocFullTextSearchTests"; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; #region CompositeFullTextIndex @@ -20,7 +20,7 @@ protected override ITestStoreFactory TestStoreFactory [ConditionalFact] public async Task Validate_composite_full_text_index_throws() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( CosmosStrings.CompositeFullTextIndex( @@ -60,7 +60,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public async Task Validate_full_text_property_on_collection_navigation_container_creation() { var message = (await Assert.ThrowsAsync(() - => InitializeAsync())).Message; + => InitializeNonSharedTest())).Message; Assert.Equal( CosmosStrings.CreatingContainerWithFullTextOrVectorOnCollectionNotSupported("/Collection"), @@ -104,7 +104,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Validate_full_text_on_non_string_property() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())) + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())) .Message; Assert.Equal( @@ -143,7 +143,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Set_unsupported_full_text_search_default_language() { - var exception = (await Assert.ThrowsAsync(() => InitializeAsync())); + var exception = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())); Assert.Contains("The Full Text Policy contains an unsupported language xx-YY.", exception.Message); } @@ -229,7 +229,7 @@ public async Task { var exception = (await Assert.ThrowsAsync(() - => InitializeAsync())); + => InitializeNonSharedTest())); Assert.Contains("The Full Text Policy contains an unsupported language xx-YY.", exception.Message); } @@ -301,7 +301,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public async Task Default_full_text_language_is_used_for_full_text_properties_if_they_dont_specify_language_themselves() { var exception = (await Assert.ThrowsAsync(() - => InitializeAsync())); + => InitializeNonSharedTest())); Assert.Contains("The Full Text Policy contains an unsupported language xx-YY.", exception.Message); } @@ -340,7 +340,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public async Task Explicitly_setting_full_text_language_overrides_default() { var exception = - (await Assert.ThrowsAsync(() => InitializeAsync())); + await Assert.ThrowsAsync(() => InitializeNonSharedTest()); Assert.Contains("The Full Text Policy contains an unsupported language xx-YY.", exception.Message); } @@ -377,7 +377,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Enable_full_text_search_for_property_then_disable_it() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( CosmosStrings.FullTextIndexOnNonFullTextProperty( diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosSessionTokensTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosSessionTokensTest.cs index 79fa4918833..7bcddc9d42e 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosSessionTokensTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosSessionTokensTest.cs @@ -603,18 +603,18 @@ protected Test2Context() public class CosmosNonSharedSessionTokenTests(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; - protected override string StoreName => nameof(CosmosSessionTokensTest); + protected override string NonSharedStoreName => nameof(CosmosSessionTokensTest); - protected override TestStore CreateTestStore() => CosmosTestStore.Create(StoreName, (cfg) => cfg.SessionTokenManagementMode(Cosmos.Infrastructure.SessionTokenManagementMode.SemiAutomatic)); + protected override TestStore CreateTestStore() => CosmosTestStore.Create(NonSharedStoreName, (cfg) => cfg.SessionTokenManagementMode(Cosmos.Infrastructure.SessionTokenManagementMode.SemiAutomatic)); [ConditionalFact] public virtual async Task UseSessionTokens_uses_session_tokens() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Customers.Add(new Customer { Id = "1", PartitionKey = "1" }); context.OtherContainerCustomers.Add(new OtherContainerCustomer { Id = "1", PartitionKey = "1" }); @@ -646,8 +646,8 @@ await Assert.ThrowsAsync(() => context.OtherContainerCustomers. [ConditionalFact] public virtual async Task ReadItem_does_not_exist_returns_null() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var result = await context.Customers.FirstOrDefaultAsync(x => x.Id == "nonexistent" && x.PartitionKey == "nonexistent"); @@ -657,8 +657,8 @@ public virtual async Task ReadItem_does_not_exist_returns_null() [ConditionalFact] public virtual async Task Read_item_session_not_found_throws_CosmosException() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Customers.Add(new Customer { Id = "1", PartitionKey = "1" }); context.OtherContainerCustomers.Add(new OtherContainerCustomer { Id = "1", PartitionKey = "1" }); @@ -690,11 +690,11 @@ await Assert.ThrowsAsync(() => context.OtherContainerCustomers. [ConditionalFact] public virtual async Task New_context_does_not_use_same_SessionTokenStorage() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Database.UseSessionToken("A"); - using var newContext = contextFactory.CreateContext(); + using var newContext = contextFactory.CreateDbContext(); Assert.NotSame(context, newContext); Assert.Null(newContext.Database.GetSessionToken()); Assert.Equal("A", context.Database.GetSessionToken()); @@ -704,17 +704,17 @@ public virtual async Task New_context_does_not_use_same_SessionTokenStorage() [ConditionalFact] public virtual async Task Pooled_context_uses_same_SessionTokenStorage() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); DbContext contextCopy; ISessionTokenStorage sessionTokenStorageCopy; - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { contextCopy = context; context.Database.UseSessionToken("A"); sessionTokenStorageCopy = ((CosmosDatabaseWrapper)context.GetService()).SessionTokenStorage; } - using var newContext = contextFactory.CreateContext(); + using var newContext = contextFactory.CreateDbContext(); Assert.Same(newContext, contextCopy); Assert.Same(sessionTokenStorageCopy, ((CosmosDatabaseWrapper)newContext.GetService()).SessionTokenStorage); @@ -724,17 +724,17 @@ public virtual async Task Pooled_context_uses_same_SessionTokenStorage() [ConditionalFact] public virtual async Task Pooled_context_clears_SessionTokenStorage() { - var contextFactory = await InitializeAsync(addServices: services => services.Replace(ServiceDescriptor.Singleton())); + var contextFactory = await InitializeNonSharedTest(addServices: services => services.Replace(ServiceDescriptor.Singleton())); DbContext contextCopy; ISessionTokenStorage sessionTokenStorageCopy; - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { contextCopy = context; sessionTokenStorageCopy = ((CosmosDatabaseWrapper)context.GetService()).SessionTokenStorage; _sessionTokenStorage.ClearCalled = false; } - using var newContext = contextFactory.CreateContext(); + using var newContext = contextFactory.CreateDbContext(); Assert.Same(newContext, contextCopy); Assert.Same(sessionTokenStorageCopy, ((CosmosDatabaseWrapper)newContext.GetService()).SessionTokenStorage); diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosTriggersTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosTriggersTest.cs index 43d82f252ff..546c151a723 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosTriggersTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosTriggersTest.cs @@ -9,18 +9,18 @@ namespace Microsoft.EntityFrameworkCore; public class CosmosTriggersTest(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "CosmosTriggersTest"; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; [ConditionalFact] public async Task Triggers_are_executed_on_SaveChanges() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { await CreateTriggersInCosmosAsync(context); @@ -41,7 +41,7 @@ public async Task Triggers_are_executed_on_SaveChanges() Assert.Contains(logs, l => l.TriggerName == "PreInsertTrigger" && l.Operation == "INSERT"); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var product = await context.Products.SingleAsync(); product.Name = "Updated Product"; @@ -53,7 +53,7 @@ public async Task Triggers_are_executed_on_SaveChanges() Assert.Contains(logs, l => l.TriggerName == "UpdateTrigger" && l.Operation == "UPDATE"); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var product = await context.Products.SingleAsync(); context.Products.Remove(product); diff --git a/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs index 0362090e08e..0f81ad16f9a 100644 --- a/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/EndToEndCosmosTest.cs @@ -17,7 +17,7 @@ public class EndToEndCosmosTest(NonSharedFixture fixture) : NonSharedModelTestBa [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_end_to_end(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(), shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -113,7 +113,7 @@ public async Task Can_add_update_delete_end_to_end(bool transactionalBatch) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_detached_entity_end_to_end(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(), shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -180,7 +180,7 @@ public async Task Can_add_update_delete_detached_entity_end_to_end(bool transact [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_untracked_properties(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(), shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -266,7 +266,7 @@ public async Task Can_add_update_untracked_properties(bool transactionalBatch) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_end_to_end_with_Guid(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(b => { b.Property(c => c.Id).ToJsonProperty("id"); @@ -322,7 +322,7 @@ public async Task Can_add_update_delete_end_to_end_with_Guid(bool transactionalB [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_end_to_end_with_DateTime(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(b => { b.Property(c => c.Id); @@ -419,7 +419,7 @@ private class CustomerNoPartitionKey [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_with_dateTime_string_end_to_end(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( b => b.Entity(), shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -471,7 +471,7 @@ public async Task Can_add_update_delete_with_dateTime_string_end_to_end(bool tra [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Entities_with_null_PK_can_be_added_with_normal_use_of_DbContext_methods_and_have_id_shadow_value_and_PK_created(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( usePooling: false, shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -495,7 +495,7 @@ public async Task Entities_with_null_PK_can_be_added_with_normal_use_of_DbContex [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Entities_can_be_tracked_with_normal_use_of_DbContext_methods_and_have_correct_resultant_state_and_id_shadow_value(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( usePooling: false, shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -770,7 +770,7 @@ private async Task Can_add_update_delete_with_collection( Action onModelBuilder = null) where TCollection : class { - var contextFactory = await InitializeAsync>( + var contextFactory = await InitializeNonSharedTest>( shouldLogCategory: _ => true, onModelCreating: onModelBuilder, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -842,7 +842,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public async Task Can_read_with_find_with_resource_id() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); const int pk1 = 1; const int pk2 = 2; @@ -906,7 +906,7 @@ await context.AddAsync( [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Find_with_empty_resource_id_throws(bool transactionalBatch) { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); using (var context = CreateContext(contextFactory, transactionalBatch)) { @@ -921,7 +921,7 @@ public async Task Find_with_empty_resource_id_throws(bool transactionalBatch) [ConditionalFact] public async Task Can_read_with_find_with_partition_key_and_value_generator() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, addServices: s => s.AddSingleton()); @@ -986,7 +986,7 @@ await context.AddAsync( [ConditionalFact] public async Task Can_read_with_find_with_partition_key_without_value_generator() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); const int pk1 = 1; @@ -1046,7 +1046,7 @@ public async Task Can_read_with_find_with_partition_key_without_value_generator( [ConditionalFact] public async Task Can_read_with_find_with_partition_key_not_part_of_primary_key() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1081,7 +1081,7 @@ public async Task Can_read_with_find_with_partition_key_not_part_of_primary_key( [ConditionalFact] public async Task Can_read_with_find_without_partition_key() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1107,7 +1107,7 @@ public async Task Can_read_with_find_without_partition_key() [ConditionalFact] public async Task Can_read_with_find_with_PK_partition_key() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); var customer = new CustomerGuid { Id = Guid.NewGuid(), Name = "Theon" }; @@ -1131,7 +1131,7 @@ public async Task Can_read_with_find_with_PK_partition_key() [ConditionalFact] public async Task Can_read_with_find_with_PK_resource_id() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); var customer = new CustomerWithResourceId { id = "42", Name = "Theon" }; @@ -1281,7 +1281,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_use_detached_entities_without_discriminators(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1330,7 +1330,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_update_unmapped_properties(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1389,7 +1389,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_use_non_persisted_properties(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1495,7 +1495,7 @@ public DbSet Customers [ConditionalFact] public async Task Using_a_conflicting_incompatible_id_throws() { - var contextFactory = await InitializeAsync(shouldLogCategory: _ => true); + var contextFactory = await InitializeNonSharedTest(shouldLogCategory: _ => true); using var context = CreateContext(contextFactory, false); @@ -1523,7 +1523,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Can_add_update_delete_end_to_end_with_conflicting_id(bool transactionalBatch) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined))); @@ -1589,7 +1589,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, InlineData(true), InlineData(false)] public async Task Can_have_non_string_property_named_Discriminator(bool useDiscriminator) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( shouldLogCategory: _ => true, onModelCreating: b => { @@ -1674,7 +1674,7 @@ OFFSET 0 LIMIT 1 protected virtual TContext CreateContext(ContextFactory factory, bool transactionalBatch) where TContext : DbContext { - var context = factory.CreateContext(); + var context = factory.CreateDbContext(); if (transactionalBatch) { context.Database.AutoTransactionBehavior = AutoTransactionBehavior.Always; @@ -1702,10 +1702,10 @@ private void AssertSql(DbContext context, params string[] expected) protected ListLoggerFactory LoggerFactory { get; } - protected override string StoreName + protected override string NonSharedStoreName => nameof(EndToEndCosmosTest); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; protected ContextFactory ContextFactory { get; private set; } @@ -1715,7 +1715,7 @@ protected async Task InitializeAsync( Func onConfiguring = null, Func seed = null, bool sensitiveLogEnabled = true) - => ContextFactory = await InitializeAsync( + => ContextFactory = await InitializeNonSharedTest( onModelCreating, seed: seed, shouldLogCategory: _ => true, diff --git a/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs index de421a17741..2b287e85924 100644 --- a/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/JsonTypesCosmosTest.cs @@ -267,6 +267,6 @@ public override Task Can_read_write_polygon_typed_as_nullable_geometry_as_GeoJso // No built-in JSON support for spatial types in the Cosmos provider => Assert.ThrowsAsync(base.Can_read_write_polygon_typed_as_nullable_geometry_as_GeoJson); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; } diff --git a/test/EFCore.Cosmos.FunctionalTests/MaterializationInterceptionCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/MaterializationInterceptionCosmosTest.cs index 926db5925c5..86ab4893198 100644 --- a/test/EFCore.Cosmos.FunctionalTests/MaterializationInterceptionCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/MaterializationInterceptionCosmosTest.cs @@ -58,6 +58,6 @@ public override Task Intercept_query_materialization_for_empty_constructor(bool public override Task Intercept_query_materialization_for_full_constructor(bool inject, bool usePooling) => base.Intercept_query_materialization_for_full_constructor(inject, usePooling); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocJsonQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocJsonQueryCosmosTest.cs index 9ac108f1d15..8aac913ff9f 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocJsonQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocJsonQueryCosmosTest.cs @@ -1636,9 +1636,9 @@ protected static async Task AssertTranslationFailed(Func query) (await Assert.ThrowsAsync(query)) .Message); - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) => builder.ConfigureWarnings(b => b.Ignore(CosmosEventId.NoPartitionKeyDefined)); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs index 8920f090bad..2de10459392 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/AdHocMiscellaneousQueryCosmosTest.cs @@ -16,11 +16,11 @@ public class AdHocMiscellaneousQueryCosmosTest(NonSharedFixture fixture) : NonSh [ConditionalFact] public virtual async Task Project_all_types_entity_with_missing_scalars() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set(); @@ -153,7 +153,7 @@ public enum JsonEnum [ConditionalFact] public virtual async Task Enum_partition_key() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: b => b.Entity().HasPartitionKey(d => d.MemberType), seed: async context => { @@ -161,7 +161,7 @@ public virtual async Task Enum_partition_key() await context.SaveChangesAsync(); }); - await using (var context = contextFactory.CreateContext()) + await using (var context = contextFactory.CreateDbContext()) { var admin = await context.Members.Where(p => p.MemberType == Context34911.MemberType.Admin).SingleAsync(); Assert.Equal("Some Admin", admin.Name); @@ -198,84 +198,84 @@ public enum MemberType [ConditionalFact] public virtual async Task Min_over_value_type_containing_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().MinAsync(p => p.NullableVal)); } [ConditionalFact] public virtual async Task Min_over_value_type_containing_all_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.NullableVal == null).MinAsync(p => p.NullableVal)); } [ConditionalFact] public virtual async Task Min_over_reference_type_containing_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().MinAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Min_over_reference_type_containing_all_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.NullableRef == null).MinAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Min_over_reference_type_containing_no_data() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.Id < 0).MinAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Max_over_value_type_containing_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Equal(3.14, await context.Set().MaxAsync(p => p.NullableVal)); } [ConditionalFact] public virtual async Task Max_over_value_type_containing_all_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.NullableVal == null).MaxAsync(p => p.NullableVal)); } [ConditionalFact] public virtual async Task Max_over_reference_type_containing_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Equal("Value", await context.Set().MaxAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Max_over_reference_type_containing_all_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.NullableRef == null).MaxAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Max_over_reference_type_containing_no_data() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.Id < 0).MaxAsync(p => p.NullableRef)); } [ConditionalFact] public virtual async Task Average_over_value_type_containing_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().AverageAsync(p => p.NullableVal)); } [ConditionalFact] public virtual async Task Average_over_value_type_containing_all_nulls() { - await using var context = (await InitializeAsync()).CreateContext(); + await using var context = (await InitializeNonSharedTest()).CreateDbContext(); Assert.Null(await context.Set().Where(e => e.NullableVal == null).AverageAsync(p => p.NullableVal)); } @@ -311,11 +311,11 @@ public class Product [ConditionalFact] public virtual async Task Enum_discriminator_with_value_converter_on_derived_dbset() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating36329, seed: Seed36329); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); // This should not throw an InvalidCastException var dog = await context.Dogs.SingleAsync(x => x.Id == "123"); @@ -391,8 +391,8 @@ public enum PetType36329 [ConditionalFact] public virtual async Task Coalesce_in_conditional_with_value_conversion() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .OrderBy(e => e.Id) @@ -440,12 +440,12 @@ public FooConverter() #endregion - protected override string StoreName + protected override string NonSharedStoreName => "AdHocMiscellaneousQueryTests"; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) => builder.ConfigureWarnings(b => b.Ignore(CosmosEventId.NoPartitionKeyDefined)); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; } diff --git a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs index 3bf5e5141c8..1bb335b8012 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Scaffolding/CompiledModelCosmosTest.cs @@ -667,7 +667,7 @@ protected override int ExpectedComplexTypeProperties protected override TestHelpers TestHelpers => CosmosTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; protected override BuildSource AddReferences(BuildSource build, [CallerFilePath] string filePath = "") diff --git a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTest.cs b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTest.cs index fe1b5b8b4fa..789b7d12894 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTest.cs @@ -5,6 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Update; public class CosmosBulkEndToEndTest(NonSharedFixture fixture) : EndToEndCosmosTest(fixture), IClassFixture { - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).UseCosmos(x => x.BulkExecutionEnabled()).ConfigureWarnings(x => x.Ignore(CosmosEventId.BulkExecutionWithTransactionalBatch)); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder).UseCosmos(x => x.BulkExecutionEnabled()).ConfigureWarnings(x => x.Ignore(CosmosEventId.BulkExecutionWithTransactionalBatch)); } diff --git a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTestNoBatching.cs b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTestNoBatching.cs index 4d7a68d5ded..df024e7b508 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTestNoBatching.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkEndToEndTestNoBatching.cs @@ -5,8 +5,8 @@ namespace Microsoft.EntityFrameworkCore.Update; public class CosmosBulkEndToEndTestNoBatching(NonSharedFixture fixture) : EndToEndCosmosTest(fixture), IClassFixture { - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).UseCosmos(x => x.BulkExecutionEnabled()); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder).UseCosmos(x => x.BulkExecutionEnabled()); protected override TContext CreateContext(ContextFactory factory, bool transactionalBatch) { diff --git a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkExecutionTest.cs b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkExecutionTest.cs index 329c88c653c..78e3e119364 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkExecutionTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Update/CosmosBulkExecutionTest.cs @@ -5,15 +5,15 @@ namespace Microsoft.EntityFrameworkCore.Update; public class CosmosBulkExecutionTest(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName => nameof(CosmosBulkExecutionTest); + protected override string NonSharedStoreName => nameof(CosmosBulkExecutionTest); - protected override ITestStoreFactory TestStoreFactory => CosmosTestStoreFactory.Instance; + protected override ITestStoreFactory NonSharedTestStoreFactory => CosmosTestStoreFactory.Instance; [ConditionalFact] public virtual async Task DoesNotBatchSingleBatchableWrite() { - var contextFactory = await InitializeAsync(onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled()).ConfigureWarnings(x => x.Ignore(CosmosEventId.BulkExecutionWithTransactionalBatch))); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled()).ConfigureWarnings(x => x.Ignore(CosmosEventId.BulkExecutionWithTransactionalBatch))); + using var context = contextFactory.CreateDbContext(); context.Add(new Customer() { PartitionKey = "4" }); context.AddRange(Enumerable.Range(0, 3).Select(x => new Customer())); @@ -32,8 +32,8 @@ public virtual async Task DoesNotBatchSingleBatchableWrite() [ConditionalFact] public async Task SessionEnabled_Throws() { - var contextFactory = await InitializeAsync(onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled().SessionTokenManagementMode(Cosmos.Infrastructure.SessionTokenManagementMode.SemiAutomatic))); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled().SessionTokenManagementMode(Cosmos.Infrastructure.SessionTokenManagementMode.SemiAutomatic))); + using var context = contextFactory.CreateDbContext(); context.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never; context.Database.UseSessionToken("0:-1#1"); context.Add(new Customer()); @@ -45,8 +45,8 @@ public async Task SessionEnabled_Throws() [ConditionalFact] public async Task Trigger_Throws() { - var contextFactory = await InitializeAsync(onModelCreating: (b) => b.Entity().HasTrigger(StoreName, Azure.Cosmos.Scripts.TriggerType.Post, Azure.Cosmos.Scripts.TriggerOperation.Create), onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled())); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(onModelCreating: (b) => b.Entity().HasTrigger(NonSharedStoreName, Azure.Cosmos.Scripts.TriggerType.Post, Azure.Cosmos.Scripts.TriggerOperation.Create), onConfiguring: (cfg) => cfg.UseCosmos(c => c.BulkExecutionEnabled())); + using var context = contextFactory.CreateDbContext(); context.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never; context.Add(new Customer()); var ex = await Assert.ThrowsAsync(() => context.SaveChangesAsync()); diff --git a/test/EFCore.InMemory.FunctionalTests/JsonTypesInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/JsonTypesInMemoryTest.cs index e4852a7c5c7..ee464409088 100644 --- a/test/EFCore.InMemory.FunctionalTests/JsonTypesInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/JsonTypesInMemoryTest.cs @@ -39,6 +39,6 @@ public override Task Can_read_write_polygon_typed_as_geometry() // No built-in JSON support for spatial types in the in-memory provider => Assert.ThrowsAsync(base.Can_read_write_polygon_typed_as_geometry); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; } diff --git a/test/EFCore.InMemory.FunctionalTests/MaterializationInterceptionInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/MaterializationInterceptionInMemoryTest.cs index 20a076add9f..d1a4fe87ec6 100644 --- a/test/EFCore.InMemory.FunctionalTests/MaterializationInterceptionInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/MaterializationInterceptionInMemoryTest.cs @@ -18,9 +18,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(c => c.Ignore(InMemoryEventId.TransactionIgnoredWarning)); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder).ConfigureWarnings(c => c.Ignore(InMemoryEventId.TransactionIgnoredWarning)); } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/AdHocAdvancedMappingsQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/AdHocAdvancedMappingsQueryInMemoryTest.cs index 029068fc98d..87b6958afa2 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/AdHocAdvancedMappingsQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/AdHocAdvancedMappingsQueryInMemoryTest.cs @@ -5,6 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocAdvancedMappingsQueryInMemoryTest(NonSharedFixture fixture) : AdHocAdvancedMappingsQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/AdHocManyToManyQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/AdHocManyToManyQueryInMemoryTest.cs index 5c424febed8..e2c8078fe73 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/AdHocManyToManyQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/AdHocManyToManyQueryInMemoryTest.cs @@ -5,6 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocManyToManyQueryInMemoryTest(NonSharedFixture fixture) : AdHocManyToManyQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/AdHocMiscellaneousQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/AdHocMiscellaneousQueryInMemoryTest.cs index 3bff6542a8d..52b6e7a3368 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/AdHocMiscellaneousQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/AdHocMiscellaneousQueryInMemoryTest.cs @@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocMiscellaneousQueryInMemoryTest(NonSharedFixture fixture) : AdHocMiscellaneousQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; public override Task Explicitly_compiled_query_does_not_add_cache_entry() diff --git a/test/EFCore.InMemory.FunctionalTests/Query/AdHocNavigationsQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/AdHocNavigationsQueryInMemoryTest.cs index 219305b81b7..b1a7c364f2e 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/AdHocNavigationsQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/AdHocNavigationsQueryInMemoryTest.cs @@ -5,6 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocNavigationsQueryInMemoryTest(NonSharedFixture fixture) : AdHocNavigationsQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/AdHocQueryFiltersQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/AdHocQueryFiltersQueryInMemoryTest.cs index a79450ffa0c..79ce3ed56c9 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/AdHocQueryFiltersQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/AdHocQueryFiltersQueryInMemoryTest.cs @@ -10,13 +10,13 @@ public class AdHocQueryFiltersQueryInMemoryTest(NonSharedFixture fixture) : AdHo [ConditionalFact] public virtual async Task GroupJoin_SelectMany_gets_flattened() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using (var context = contextFactory.CreateDbContext()) { var query = context.CustomerFilters.ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set().ToList(); @@ -128,6 +128,6 @@ public class CustomerView19708 #endregion - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/OwnedEntityQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/OwnedEntityQueryInMemoryTest.cs index d70d06570cf..b3548e6d3ef 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/OwnedEntityQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/OwnedEntityQueryInMemoryTest.cs @@ -5,15 +5,15 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OwnedEntityQueryInMemoryTest(NonSharedFixture fixture) : OwnedEntityQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Expand_owned_navigation_as_optional_always(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Include(c => c.Bar); var foo = async ? await query.FirstOrDefaultAsync() @@ -63,8 +63,8 @@ protected class Foo [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_references_on_same_level_expanded_at_different_times_around_take(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); await base.Owned_references_on_same_level_expanded_at_different_times_around_take_helper(context, async); } @@ -72,8 +72,8 @@ public virtual async Task Owned_references_on_same_level_expanded_at_different_t [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_references_on_same_level_nested_expanded_at_different_times_around_take(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); await base.Owned_references_on_same_level_nested_expanded_at_different_times_around_take_helper(context, async); } diff --git a/test/EFCore.InMemory.FunctionalTests/Query/SharedTypeQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/SharedTypeQueryInMemoryTest.cs index c5e39029502..ccecf6c6563 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/SharedTypeQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/SharedTypeQueryInMemoryTest.cs @@ -5,16 +5,16 @@ namespace Microsoft.EntityFrameworkCore.Query; public class SharedTypeQueryInMemoryTest(NonSharedFixture fixture) : SharedTypeQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Can_use_shared_type_entity_type_in_ToInMemoryQuery(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var data = context.Set(); diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs index 353a62dc3ef..7aa00f491ea 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs @@ -527,11 +527,11 @@ protected override bool ShouldUseFullName(string shortTypeName) protected override TestHelpers TestHelpers => InMemoryTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => InMemoryTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w.Ignore(CoreEventId.CollectionWithoutComparer)); protected override BuildSource AddReferences(BuildSource build, [CallerFilePath] string filePath = "") diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs index 340e903d6d3..d07ca69bc64 100644 --- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesRelationalTestBase.cs @@ -9,13 +9,13 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public abstract class NonSharedModelBulkUpdatesRelationalTestBase(NonSharedFixture fixture) : NonSharedModelBulkUpdatesTestBase(fixture) { - protected override string StoreName + protected override string NonSharedStoreName => "NonSharedModelBulkUpdatesTests"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_aggregate_root_when_table_sharing_with_non_owned_throws(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().HasOne().WithOne().HasForeignKey(e => e.Id); @@ -25,14 +25,14 @@ public virtual async Task Delete_aggregate_root_when_table_sharing_with_non_owne await AssertTranslationFailedWithDetails( RelationalStrings.ExecuteDeleteOnTableSplitting(nameof(Owner)), () => AssertDelete( - async, contextFactory.CreateContext, + async, contextFactory.CreateDbContext, context => context.Set(), rowsAffectedCount: 0)); } [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_main_table_in_entity_with_entity_splitting(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => mb.Entity() .ToTable("Blogs") .SplitToTable( @@ -49,7 +49,7 @@ public virtual async Task Update_main_table_in_entity_with_entity_splitting(bool await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set(), s => s.SetProperty(b => b.CreationTimestamp, b => new DateTime(2020, 1, 1)), rowsAffectedCount: 1); @@ -58,7 +58,7 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_non_main_table_in_entity_with_entity_splitting(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => mb.Entity() .ToTable("Blogs") .SplitToTable( @@ -75,7 +75,7 @@ public virtual async Task Update_non_main_table_in_entity_with_entity_splitting( await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set(), s => s .SetProperty(b => b.Title, b => b.Rating.ToString()) @@ -86,11 +86,11 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] // #34677 public virtual async Task Delete_with_view_mapping(bool async) { - var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + var contextFactory = await InitializeNonSharedTest(seed: async context => await context.Seed()); await AssertDelete( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Foos, rowsAffectedCount: 1); } @@ -98,11 +98,11 @@ await AssertDelete( [ConditionalTheory, MemberData(nameof(IsAsyncData))] // #34677 public virtual async Task Update_with_view_mapping(bool async) { - var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + var contextFactory = await InitializeNonSharedTest(seed: async context => await context.Seed()); await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Foos, s => s.SetProperty(f => f.Data, "Updated"), rowsAffectedCount: 1); @@ -111,11 +111,11 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] // #34677 public virtual async Task Update_complex_type_with_view_mapping(bool async) { - var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + var contextFactory = await InitializeNonSharedTest(seed: async context => await context.Seed()); await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Foos, s => s.SetProperty(f => f.ComplexThing, new Context34677.ComplexThing { Prop1 = 3, Prop2 = 4 }), rowsAffectedCount: 1); @@ -124,11 +124,11 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] // #34677 public virtual async Task Update_complex_type_property_with_view_mapping(bool async) { - var contextFactory = await InitializeAsync(seed: async context => await context.Seed()); + var contextFactory = await InitializeNonSharedTest(seed: async context => await context.Seed()); await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Foos, s => s.SetProperty(f => f.ComplexThing.Prop1, 6), rowsAffectedCount: 1); diff --git a/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs index 806b7979913..862a924b9fa 100644 --- a/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/EntitySplittingTestBase.cs @@ -75,7 +75,7 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync( public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); - protected override string StoreName + protected override string NonSharedStoreName => "EntitySplittingTest"; protected TestSqlLoggerFactory TestSqlLoggerFactory @@ -103,7 +103,7 @@ protected async Task InitializeAsync( Func onConfiguring = null, Func seed = null, bool sensitiveLogEnabled = true) - => ContextFactory = await InitializeAsync( + => ContextFactory = await InitializeNonSharedTest( onModelCreating, seed: seed, shouldLogCategory: _ => true, @@ -117,7 +117,7 @@ protected async Task InitializeAsync( ); protected virtual EntitySplittingContext CreateContext() - => ContextFactory.CreateContext(); + => ContextFactory.CreateDbContext(); public override async Task DisposeAsync() { diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs index ce0b366410e..2d2a35574fa 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocAdvancedMappingsQueryRelationalTestBase.cs @@ -21,9 +21,9 @@ protected void AssertSql(params string[] expected) [ConditionalFact] public virtual async Task Two_similar_complex_properties_projected_with_split_query1() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Offers .Include(e => e.Variations) .ThenInclude(v => v.Nested) @@ -41,9 +41,9 @@ public virtual async Task Two_similar_complex_properties_projected_with_split_qu [ConditionalFact] public virtual async Task Two_similar_complex_properties_projected_with_split_query2() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Offers .Include(e => e.Variations) .ThenInclude(v => v.Nested) @@ -60,9 +60,9 @@ public virtual async Task Two_similar_complex_properties_projected_with_split_qu [ConditionalFact] public virtual async Task Projecting_one_of_two_similar_complex_types_picks_the_correct_one() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Cs .Where(x => x.B.AId.Value == 1) diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocComplexTypeQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocComplexTypeQueryRelationalTestBase.cs index 0d8728fee8b..74c255a1248 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocComplexTypeQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocComplexTypeQueryRelationalTestBase.cs @@ -10,9 +10,9 @@ public abstract class AdHocComplexTypeQueryRelationalTestBase(NonSharedFixture f [ConditionalFact] public virtual async Task Complex_json_collection_inside_left_join_subquery() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); _ = await context.Set().Include(p => p.Child).ToListAsync(); } @@ -57,8 +57,8 @@ public record CareNeedAnswer [ConditionalFact] public virtual async Task Select_TPC_base_with_ComplexType() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var count = await context.TpcBases.ToListAsync(); @@ -120,7 +120,7 @@ public class AnotherComplexThing [ConditionalFact] public virtual async Task Complex_type_on_an_entity_mapped_to_view_and_table() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => mb.Entity(eb => eb .ToTable("Blogs") .ToView("BlogsView") @@ -144,7 +144,7 @@ public virtual async Task Complex_type_on_an_entity_mapped_to_view_and_table() string Q(string name) => sqlGenerationHelper.DelimitIdentifier(name); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = await context.Set().SingleAsync(); diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryRelationalTestBase.cs index 9266b68ca87..e62be31c9f2 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocJsonQueryRelationalTestBase.cs @@ -132,11 +132,11 @@ protected override void OnModelCreating33046(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Project_entity_with_optional_json_entity_owned_by_required_json() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating34293, seed: ctx => ctx.Seed()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var entityProjection = await context.Set().ToListAsync(); Assert.Equal(3, entityProjection.Count); @@ -145,11 +145,11 @@ public virtual async Task Project_entity_with_optional_json_entity_owned_by_requ [ConditionalFact] public virtual async Task Project_required_json_entity() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating34293, seed: ctx => ctx.Seed()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var rootProjection = await context.Set().AsNoTracking().Where(x => x.Id != 3).Select(x => x.Json).ToListAsync(); @@ -171,11 +171,11 @@ public virtual async Task Project_required_json_entity() [ConditionalFact] public virtual async Task Project_optional_json_entity_owned_by_required_json_entity() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating34293, seed: ctx => ctx.Seed()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var leafProjection = await context.Set().AsNoTracking().Select(x => x.Json.Required.Optional).ToListAsync(); Assert.Equal(3, leafProjection.Count); } @@ -567,12 +567,12 @@ protected override void OnModelCreatingBadJsonProperties(ModelBuilder modelBuild [ConditionalFact] // #36145 public virtual async Task Entity_splitting_with_owned_json() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingEntitySplitting, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedEntitySplitting); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var result = await context.Set().SingleAsync(); Assert.Equal("split content", result.PropertyInOtherTable); @@ -625,7 +625,7 @@ public class JsonEntity [ConditionalFact] public virtual async Task HasJsonPropertyName() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: m => m.Entity().ComplexProperty(e => e.Json, b => { @@ -660,7 +660,7 @@ public virtual async Task HasJsonPropertyName() return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); Assert.Equal(1, await context.Set().CountAsync(e => e.Json.String == "foo")); Assert.Equal(1, await context.Set().CountAsync(e => e.Json.Nested.Int == 1)); diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs index b883eb01e09..dc54e970652 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs @@ -29,11 +29,11 @@ protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode( [ConditionalFact] public async Task Query_when_null_key_in_database_should_throw() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => o.EnableDetailedErrors(), seed: Seed2951); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); Assert.Equal( RelationalStrings.ErrorMaterializingPropertyNullReference(nameof(Context2951.ZeroKey2951), "Id", typeof(int)), @@ -63,11 +63,11 @@ public class ZeroKey2951 [ConditionalFact] public virtual async Task GroupJoin_Anonymous_projection_GroupBy_Aggregate_join_elimination() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => o.ConfigureWarnings(w => w.Log(CoreEventId.FirstWithoutOrderByAndFilterWarning))); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = (from e in context.Set() join a in context.Set() @@ -81,7 +81,7 @@ from a in grouping.DefaultIfEmpty() Assert.Empty(query); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = (from e in context.Set() join a in context.Set() @@ -98,7 +98,7 @@ from m in grouping2.DefaultIfEmpty() Assert.Empty(query); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = (from e in context.Set() join a in context.Set() @@ -163,8 +163,8 @@ public class MaumarEntity11818 [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Multiple_different_entity_type_from_different_namespaces(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); //var good1 = context.Set().FromSqlRaw(@"SELECT 1 AS MyValue").ToList(); // OK //var good2 = context.Set().FromSqlRaw(@"SELECT 1 AS MyValue").ToList(); // OK var bad = context.Set().FromSqlRaw(@"SELECT cast(null as int) AS MyValue").ToList(); // Exception @@ -195,8 +195,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task StoreType_for_UDF_used(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var date = new DateTime(2012, 12, 12); var query1 = context.Set().Where(x => x.SomeDate == date); @@ -244,7 +244,7 @@ public static DateTime Modify(DateTime date) [ConditionalFact] public virtual async Task Mapping_JsonElement_property_throws_a_meaningful_exception() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( CoreStrings.PropertyNotAdded(nameof(Context34752.Entity), nameof(Context34752.Entity.Json), nameof(JsonElement)), @@ -269,13 +269,13 @@ public class Entity [ConditionalTheory, MemberData(nameof(InlinedRedactingData))] public virtual async Task Check_inlined_constants_redacting(bool async, bool enableSensitiveDataLogging) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => { SetParameterizedCollectionMode(o, ParameterTranslationMode.Constant); o.EnableSensitiveDataLogging(enableSensitiveDataLogging); }); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var id = 1; var ids = new[] { id, 2, 3 }; @@ -317,9 +317,9 @@ public class TestEntity [ConditionalTheory, MemberData(nameof(IsAsyncData))] public async Task Entity_equality_with_Contains_and_Parameter(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => SetParameterizedCollectionMode(o, ParameterTranslationMode.Parameter)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); List details = [new() { Id = 1 }, new() { Id = 2 }]; var query = context.Blogs.Where(b => details.Contains(b.Details)); diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs index fb4caf63ef4..0cc80ef0c1c 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocNavigationsQueryRelationalTestBase.cs @@ -21,8 +21,8 @@ protected void AssertSql(params string[] expected) [ConditionalTheory, InlineData(true, true), InlineData(true, false), InlineData(false, true), InlineData(false, false)] public virtual async Task Select_enumerable_navigation_backed_by_collection(bool async, bool split) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Select(appEntity => appEntity.OtherEntities); if (split) diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs index 8809e92c248..607e9f45747 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocPrecompiledQueryRelationalTestBase.cs @@ -17,7 +17,7 @@ public AdHocPrecompiledQueryRelationalTestBase(NonSharedFixture fixture, ITestOu [ConditionalFact] public virtual async Task Index_no_evaluatability() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -34,7 +34,7 @@ await Test( [ConditionalFact] public virtual async Task Index_with_captured_variable() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -52,7 +52,7 @@ await Test( [ConditionalFact] public virtual async Task JsonScalar() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -91,7 +91,7 @@ public class JsonThing [ConditionalFact] public virtual async Task Materialize_non_public() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -226,7 +226,7 @@ public int? PrivateAutoPropertyExposer [ConditionalFact] public virtual async Task Projecting_property_requiring_converter_with_closure_is_not_supported() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -245,7 +245,7 @@ await Test( [ConditionalFact] public virtual async Task Projecting_expression_requiring_converter_without_closure_works() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -260,7 +260,7 @@ await Test( [ConditionalFact] public virtual async Task Projecting_entity_with_property_requiring_converter_with_closure_works() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); var options = contextFactory.GetOptions(); await Test( @@ -371,6 +371,6 @@ protected override IServiceCollection AddServices(IServiceCollection serviceColl => base.AddServices(serviceCollection) .AddScoped(); - protected override string StoreName + protected override string NonSharedStoreName => "AdHocPrecompiledQueryTest"; } diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs index 6c3731b94a8..02f39022ee6 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocQuerySplittingQueryTestBase.cs @@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocQuerySplittingQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocQuerySplittingQueryTests"; protected TestSqlLoggerFactory TestSqlLoggerFactory @@ -34,21 +34,21 @@ protected abstract DbContextOptionsBuilder SetQuerySplittingBehavior( [ConditionalFact] public virtual async Task Can_configure_SingleQuery_at_context_level() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SingleQuery)); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Parents.Include(p => p.Children1).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Parents.Include(p => p.Children1).AsSplitQuery().ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Parents.Include(p => p.Children1).Include(p => p.Children2).ToList(); } @@ -57,21 +57,21 @@ public virtual async Task Can_configure_SingleQuery_at_context_level() [ConditionalFact] public virtual async Task Can_configure_SplitQuery_at_context_level() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Parents.Include(p => p.Children1).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Parents.Include(p => p.Children1).AsSingleQuery().ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Parents.Include(p => p.Children1).Include(p => p.Children2).ToList(); } @@ -80,16 +80,16 @@ public virtual async Task Can_configure_SplitQuery_at_context_level() [ConditionalFact] public virtual async Task Unconfigured_query_splitting_behavior_throws_a_warning() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => ClearQuerySplittingBehavior(o)); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSplitQuery().ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Assert.Contains( RelationalResources.LogMultipleCollectionIncludeWarning(new TestLogger()) @@ -102,40 +102,40 @@ public virtual async Task Unconfigured_query_splitting_behavior_throws_a_warning [ConditionalFact] public virtual async Task Using_AsSingleQuery_without_context_configuration_does_not_throw_warning() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSingleQuery().ToList(); } [ConditionalFact] public virtual async Task SplitQuery_disposes_inner_data_readers() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); ((RelationalTestStore)contextFactory.TestStore).CloseConnection(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSplitQuery().ToList(); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { await context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSplitQuery().ToListAsync(); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Parents.Include(p => p.Children1).Include(p => p.Children2).OrderBy(e => e.Id).AsSplitQuery().Single(); Assert.Equal(ConnectionState.Closed, context.Database.GetDbConnection().State); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { await context.Parents.Include(p => p.Children1).Include(p => p.Children2).OrderBy(e => e.Id).AsSplitQuery().SingleAsync(); @@ -220,8 +220,8 @@ void Query(Context25225 context, Guid parentId, Guid collectionId) private async Task<(Context25225, Context25225)> CreateTwoContext25225() { var factory = await CreateContext25225Async(); - var context1 = factory.CreateContext(); - var context2 = factory.CreateContext(); + var context1 = factory.CreateDbContext(); + var context2 = factory.CreateDbContext(); // Can't run in parallel with the same connection instance. Issue #22921 Assert.NotSame(context1.Database.GetDbConnection(), context2.Database.GetDbConnection()); @@ -230,7 +230,7 @@ void Query(Context25225 context, Guid parentId, Guid collectionId) } private async Task> CreateContext25225Async() - => await InitializeAsync( + => await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery), createTestStore: CreateTestStore25225); @@ -316,11 +316,11 @@ public class CollectionViewModel [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task NoTracking_split_query_creates_only_required_instances(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); Context25400.Test.ConstructorCallCount = 0; var query = context.Set().AsNoTracking().OrderBy(e => e.Id); @@ -368,10 +368,10 @@ public Test(int value) [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task NoTrackingWithIdentityResolution_split_query_basic(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .AsNoTrackingWithIdentityResolution() .Select(blog => new { blog.Id, Posts = blog.Posts.Select(blogPost => new { blogPost.Id, blogPost.Author }).ToList() }); @@ -384,10 +384,10 @@ public virtual async Task NoTrackingWithIdentityResolution_split_query_basic(boo [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task NoTrackingWithIdentityResolution_split_query_complex(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => SetQuerySplittingBehavior(o, QuerySplittingBehavior.SplitQuery)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .AsNoTrackingWithIdentityResolution() .Select(blog => new diff --git a/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs index bfecf160bc9..fb22dfb1263 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/EntitySplittingQueryTestBase.cs @@ -2778,7 +2778,7 @@ public IQueryable Set() #region Fixture protected async Task InitializeContextFactoryAsync(Action onModelCreating) - => ContextFactory = await InitializeAsync( + => ContextFactory = await InitializeNonSharedTest( mb => { OnModelCreating(mb); @@ -2791,10 +2791,10 @@ protected async Task InitializeContextFactoryAsync(Action onModelC shouldLogCategory: _ => true); protected virtual EntitySplittingContext CreateContext() - => ContextFactory.CreateContext(); + => ContextFactory.CreateDbContext(); - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder) .UseSeeding((c, _) => { EntitySplittingData.Instance.AddSeedData((EntitySplittingContext)c); @@ -2809,7 +2809,7 @@ protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder bu public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); - protected override string StoreName + protected override string NonSharedStoreName => "EntitySplittingQueryTest"; protected TestSqlLoggerFactory TestSqlLoggerFactory diff --git a/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs index acfbdb7ddd0..17b5d862bb8 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OperatorsProceduralQueryTestBase.cs @@ -126,7 +126,7 @@ protected OperatorsProceduralQueryTestBase(NonSharedFixture fixture) ExpectedQueryRewriter = new ExpectedQueryRewritingVisitor(); } - protected override string StoreName + protected override string NonSharedStoreName => "OperatorsProceduralTest"; protected virtual async Task SeedAsync(OperatorsContext ctx) @@ -147,8 +147,8 @@ protected virtual async Task SeedAsync(OperatorsContext ctx) public virtual async Task Procedural_predicate_test_six_sources_three_pairs() { var maxDepth = 7; - var contextFactory = await InitializeAsync(seed: ctx => SeedAsync(ctx)); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: ctx => SeedAsync(ctx)); + using var context = contextFactory.CreateDbContext(); var actualSetSource = new ActualSetSource(context); while (true) @@ -193,8 +193,8 @@ public virtual async Task Procedural_predicate_test_six_sources_three_pairs() public virtual async Task Procedural_projection_test_six_sources_two_trios() { var maxDepth = 7; - var contextFactory = await InitializeAsync(seed: ctx => SeedAsync(ctx)); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: ctx => SeedAsync(ctx)); + using var context = contextFactory.CreateDbContext(); var actualSetSource = new ActualSetSource(context); while (true) diff --git a/test/EFCore.Relational.Specification.Tests/Query/OperatorsQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OperatorsQueryTestBase.cs index 8fbc2cae732..33e16d5e048 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OperatorsQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OperatorsQueryTestBase.cs @@ -9,7 +9,7 @@ public abstract class OperatorsQueryTestBase(NonSharedFixture fixture) : NonShar { protected OperatorsData ExpectedData { get; init; } = OperatorsData.Instance; - protected override string StoreName + protected override string NonSharedStoreName => "OperatorsTest"; protected virtual Task Seed(OperatorsContext ctx) @@ -29,8 +29,8 @@ protected virtual Task Seed(OperatorsContext ctx) [ConditionalFact] public virtual async Task Bitwise_and_on_expression_with_like_and_null_check_being_compared_to_false() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from o1 in ExpectedData.OperatorEntitiesString from o2 in ExpectedData.OperatorEntitiesString @@ -68,8 +68,8 @@ from o3 in context.Set() [ConditionalFact] public virtual async Task Complex_predicate_with_bitwise_and_modulo_and_negation() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e0 in ExpectedData.OperatorEntitiesLong from e1 in ExpectedData.OperatorEntitiesLong @@ -114,8 +114,8 @@ from e3 in context.Set() [ConditionalFact] public virtual async Task Complex_predicate_with_bitwise_and_arithmetic_operations() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e0 in ExpectedData.OperatorEntitiesInt from e1 in ExpectedData.OperatorEntitiesInt @@ -153,8 +153,8 @@ from e2 in context.Set() [ConditionalFact] public virtual async Task Or_on_two_nested_binaries_and_another_simple_comparison() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e1 in ExpectedData.OperatorEntitiesString from e2 in ExpectedData.OperatorEntitiesString @@ -202,8 +202,8 @@ from e5 in context.Set() [ConditionalFact] public virtual async Task Projection_with_not_and_negation_on_integer() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e3 in ExpectedData.OperatorEntitiesLong from e4 in ExpectedData.OperatorEntitiesLong @@ -227,8 +227,8 @@ from e5 in context.Set() [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Negate_on_column(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e in ExpectedData.OperatorEntitiesInt where e.Id == -e.Value @@ -248,8 +248,8 @@ public virtual async Task Negate_on_column(bool async) [ConditionalFact] public virtual async Task Double_negate_on_column() { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e in ExpectedData.OperatorEntitiesInt where -(-e.Value) == e.Value @@ -269,8 +269,8 @@ public virtual async Task Double_negate_on_column() [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Negate_on_binary_expression(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e1 in ExpectedData.OperatorEntitiesInt from e2 in ExpectedData.OperatorEntitiesInt @@ -293,8 +293,8 @@ from e2 in context.Set() [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Negate_on_like_expression(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e in ExpectedData.OperatorEntitiesString where !e.Value.StartsWith("A") @@ -315,7 +315,7 @@ public virtual async Task Negate_on_like_expression(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Concat_and_json_scalar(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => mb .Entity() .OwnsOne(o => o.Owned) @@ -327,7 +327,7 @@ public virtual async Task Concat_and_json_scalar(bool async) new Owner { Owned = new Owned { SomeProperty = "Baz" } }); return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var result = await context.Set().SingleAsync(o => "Foo" + o.Owned.SomeProperty == "FooBar"); Assert.Equal("Bar", result.Owned.SomeProperty); diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs index 4dbfe130c1c..2eab60616fe 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs @@ -21,7 +21,7 @@ protected void AssertSql(params string[] expected) [ConditionalFact] public virtual async Task An_optional_dependent_without_any_columns_and_nested_dependent_throws() { - var message = (await Assert.ThrowsAsync(() => InitializeAsync())).Message; + var message = (await Assert.ThrowsAsync(() => InitializeNonSharedTest())).Message; Assert.Equal( RelationalStrings.OptionalDependentWithDependentWithoutIdentifyingProperty(nameof(Context23198.AnOwnedTypeWithOwnedProperties)), @@ -70,8 +70,8 @@ public class AnOwnedTypeWithPrimitiveProperties2 [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Multiple_owned_reference_mapped_to_own_table_containing_owned_collection_in_split_query(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Roots.Where(e => e.Id == 3).AsSplitQuery(); var root3 = async @@ -179,8 +179,8 @@ public class Leaf [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_collection_basic_split_query(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var id = new Guid("6c1ae3e5-30b9-4c77-8d98-f02075974a0a"); var query = context.Set().Where(e => e.Id == id).AsSplitQuery(); @@ -231,8 +231,8 @@ protected class PublishTokenType25680 [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_reference_mapped_to_different_table_updated_correctly_after_subquery_pushdown(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); await base.Owned_references_on_same_level_expanded_at_different_times_around_take_helper(context, async); } @@ -240,8 +240,8 @@ public virtual async Task Owned_reference_mapped_to_different_table_updated_corr [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_reference_mapped_to_different_table_nested_updated_correctly_after_subquery_pushdown(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); await base.Owned_references_on_same_level_nested_expanded_at_different_times_around_take_helper(context, async); } @@ -276,9 +276,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_materializes_when_not_containing_another_owned_entity(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.RotRutCases.OrderBy(e => e.Buyer); var result = async @@ -307,9 +307,9 @@ public virtual async Task Owned_entity_with_all_null_properties_materializes_whe [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_entity_equality_when_not_containing_another_owned_entity(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.RotRutCases.AsNoTracking().Select(e => e.Rot).Where(e => e != null); var result = async @@ -328,9 +328,9 @@ public virtual async Task Owned_entity_with_all_null_properties_entity_equality_ [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_null_in_conditional_projection(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.RotRutCases .AsNoTracking() .OrderBy(e => e.Id) @@ -358,9 +358,9 @@ public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_n [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_non_null_in_conditional_projection(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.RotRutCases .AsNoTracking() .OrderBy(e => e.Id) @@ -388,9 +388,9 @@ public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_n [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_property_access_when_not_containing_another_owned_entity(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.RotRutCases.AsNoTracking().Select(e => e.Rot.ApartmentNo); var result = async @@ -477,8 +477,8 @@ public class Rut [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Join_selects_with_duplicating_aliases_and_owned_expansion_uniquifies_correctly(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = from monarch in context.Monarchs join magus in context.Magi.Where(x => x.Name.Contains("Bayaz")) on monarch.RulerOf equals magus.Affiliation @@ -561,8 +561,8 @@ public class MagicTool [ConditionalFact] public async Task Can_have_required_owned_type_on_derived_type() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); context.Set().ToList(); } @@ -613,8 +613,8 @@ public sealed class Child2Entity : BaseEntity; #endregion - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(c => c + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder).ConfigureWarnings(c => c .Log(RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning) .Log(RelationalEventId.OptionalDependentWithAllNullPropertiesWarning)); } diff --git a/test/EFCore.Relational.Specification.Tests/Query/SharedTypeQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/SharedTypeQueryRelationalTestBase.cs index 18cb47fa31d..ba88d3266cc 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/SharedTypeQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/SharedTypeQueryRelationalTestBase.cs @@ -19,10 +19,10 @@ protected void AssertSql(params string[] expected) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Can_use_shared_type_entity_type_in_query_filter_with_from_sql(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = async ? await query.ToListAsync() @@ -34,13 +34,13 @@ public virtual async Task Can_use_shared_type_entity_type_in_query_filter_with_f [ConditionalFact] public virtual async Task Ad_hoc_query_for_shared_type_entity_type_works() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var result = context.Database.SqlQueryRaw( - ((RelationalTestStore)TestStore).NormalizeDelimitersInRawString(@"SELECT * FROM [ViewQuery24601]")); + ((RelationalTestStore)NonSharedTestStore).NormalizeDelimitersInRawString(@"SELECT * FROM [ViewQuery24601]")); Assert.Empty(await result.ToListAsync()); } @@ -48,10 +48,10 @@ public virtual async Task Ad_hoc_query_for_shared_type_entity_type_works() [ConditionalFact] public virtual async Task Ad_hoc_query_for_default_shared_type_entity_type_throws() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); Assert.Equal( CoreStrings.ClashingSharedType("Dictionary"), diff --git a/test/EFCore.Relational.Specification.Tests/Query/ToSqlQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ToSqlQueryTestBase.cs index 3427ce511ff..9dc2789c2f5 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/ToSqlQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/ToSqlQueryTestBase.cs @@ -5,14 +5,14 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class ToSqlQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "ToSqlQueryTests"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] // Issue #27629 public virtual async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: async c => { var author = new Author { Name = "Toast", Posts = { new Post { Title = "Sausages of the world!" } } }; @@ -25,7 +25,7 @@ public virtual async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool as await c.SaveChangesAsync(); }); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var authors = await (from o in context.Authors diff --git a/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs index 894a8dcf14f..e16b309e589 100644 --- a/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Scaffolding/CompiledModelRelationalTestBase.cs @@ -1357,7 +1357,7 @@ protected override BuildSource AddReferences(BuildSource build, [CallerFilePath] return build; } - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w.Ignore(RelationalEventId.ForeignKeyTpcPrincipalWarning)); } diff --git a/test/EFCore.Relational.Specification.Tests/TPTTableSplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/TPTTableSplittingTestBase.cs index 0f928877fc5..8202b76dc4d 100644 --- a/test/EFCore.Relational.Specification.Tests/TPTTableSplittingTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TPTTableSplittingTestBase.cs @@ -19,7 +19,7 @@ public override Task Can_use_optional_dependents_with_shared_concurrency_tokens( public override Task ExecuteDelete_throws_for_table_sharing(bool async) => Task.CompletedTask; - protected override string StoreName + protected override string NonSharedStoreName => "TPTTableSplittingTest"; protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs index d1068c3dfae..b4483d35986 100644 --- a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs @@ -810,10 +810,10 @@ await TestHelpers.ExecuteWithStrategyInTransactionAsync( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Optional_dependent_without_required_property(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: e => e.ConfigureWarnings(w => w.Log(RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning))); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.DetailedOrders.Where(o => o.Status == OrderStatus.Pending); @@ -894,7 +894,7 @@ public enum OrderStatus public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); - protected override string StoreName + protected override string NonSharedStoreName => "TableSplittingTest"; protected TestSqlLoggerFactory TestSqlLoggerFactory @@ -972,11 +972,11 @@ protected virtual void OnSharedModelCreating(ModelBuilder modelBuilder) } protected async Task InitializeAsync(Action onModelCreating, bool seed = true) - => ContextFactory = await InitializeAsync( + => ContextFactory = await InitializeNonSharedTest( onModelCreating, shouldLogCategory: _ => true, seed: seed ? c => c.SeedAsync() : null); protected async Task InitializeSharedAsync(Action onModelCreating, bool sensitiveLogEnabled = true) - => SharedContextFactory = await InitializeAsync( + => SharedContextFactory = await InitializeNonSharedTest( onModelCreating, shouldLogCategory: _ => true, onConfiguring: options => @@ -988,10 +988,10 @@ protected async Task InitializeSharedAsync(Action onModelCreating, ); protected virtual TransportationContext CreateContext() - => ContextFactory.CreateContext(); + => ContextFactory.CreateDbContext(); protected virtual SharedTableContext CreateSharedContext() - => SharedContextFactory.CreateContext(); + => SharedContextFactory.CreateDbContext(); public override async Task DisposeAsync() { diff --git a/test/EFCore.Relational.Specification.Tests/Update/NonSharedModelUpdatesTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/NonSharedModelUpdatesTestBase.cs index 44c8d19a3e1..fa2c97c10df 100644 --- a/test/EFCore.Relational.Specification.Tests/Update/NonSharedModelUpdatesTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Update/NonSharedModelUpdatesTestBase.cs @@ -8,13 +8,13 @@ namespace Microsoft.EntityFrameworkCore.Update; public abstract class NonSharedModelUpdatesTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "NonSharedModelUpdatesTestBase"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] // Issue #29356 public virtual async Task Principal_and_dependent_roundtrips_with_cycle_breaking(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity(b => @@ -93,7 +93,7 @@ private class Book [ConditionalTheory, MemberData(nameof(IsAsyncData))] // Issue #29379 public virtual async Task DbUpdateException_Entries_is_correct_with_multiple_inserts(bool async) { - var contextFactory = await InitializeAsync(onModelCreating: mb => mb.Entity().HasIndex(b => b.Name).IsUnique()); + var contextFactory = await InitializeNonSharedTest(onModelCreating: mb => mb.Entity().HasIndex(b => b.Name).IsUnique()); await ExecuteWithStrategyInTransactionAsync( contextFactory, @@ -127,7 +127,7 @@ public class Blog [ConditionalTheory, MemberData(nameof(IsAsyncData))] // Issue #36059 public virtual async Task Replacing_owned_entity_with_FK_to_another_entity(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity(b => @@ -241,7 +241,7 @@ protected virtual Task ExecuteWithStrategyInTransactionAsync( Func? nestedTestOperation2 = null, Func? nestedTestOperation3 = null) => TestHelpers.ExecuteWithStrategyInTransactionAsync( - contextFactory.CreateContext, UseTransaction, testOperation, nestedTestOperation1, nestedTestOperation2, nestedTestOperation3); + contextFactory.CreateDbContext, UseTransaction, testOperation, nestedTestOperation1, nestedTestOperation2, nestedTestOperation3); public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction()); diff --git a/test/EFCore.Relational.Specification.Tests/Update/StoredProcedureUpdateTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/StoredProcedureUpdateTestBase.cs index 5f0840a2cac..bdbb51d4dd2 100644 --- a/test/EFCore.Relational.Specification.Tests/Update/StoredProcedureUpdateTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Update/StoredProcedureUpdateTestBase.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Update; public abstract class StoredProcedureUpdateTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "StoredProcedureUpdateTest"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] @@ -18,7 +18,7 @@ protected override string StoreName protected async Task Insert_with_output_parameter(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .InsertUsingStoredProcedure( nameof(Entity) + "_Insert", @@ -27,7 +27,7 @@ protected async Task Insert_with_output_parameter(bool async, string createSproc .HasParameter(w => w.Id, pb => pb.IsOutput())), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var newEntity1 = new Entity { Name = "New" }; context.Set().Add(newEntity1); @@ -44,7 +44,7 @@ protected async Task Insert_with_output_parameter(bool async, string createSproc protected async Task Insert_twice_with_output_parameter(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .InsertUsingStoredProcedure( nameof(Entity) + "_Insert", @@ -53,7 +53,7 @@ protected async Task Insert_twice_with_output_parameter(bool async, string creat .HasParameter(w => w.Id, pb => pb.IsOutput())), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var (newEntity1, newEntity2) = (new Entity { Name = "New1" }, new Entity { Name = "New2" }); @@ -72,14 +72,14 @@ protected async Task Insert_twice_with_output_parameter(bool async, string creat protected async Task Insert_with_result_column(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity().InsertUsingStoredProcedure( nameof(Entity) + "_Insert", spb => spb .HasParameter(w => w.Name) .HasResultColumn(w => w.Id)), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Foo" }; context.Set().Add(entity); @@ -96,7 +96,7 @@ protected async Task Insert_with_result_column(bool async, string createSprocSql protected async Task Insert_with_two_result_columns(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.AdditionalProperty).HasComputedColumnSql("8"); @@ -109,7 +109,7 @@ protected async Task Insert_with_two_result_columns(bool async, string createSpr }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new EntityWithAdditionalProperty { Name = "Foo" }; context.Set().Add(entity); @@ -129,7 +129,7 @@ protected async Task Insert_with_two_result_columns(bool async, string createSpr protected async Task Insert_with_output_parameter_and_result_column(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.AdditionalProperty).HasComputedColumnSql("8"); @@ -142,7 +142,7 @@ protected async Task Insert_with_output_parameter_and_result_column(bool async, }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new EntityWithAdditionalProperty { Name = "Foo" }; context.Set().Add(entity); @@ -161,7 +161,7 @@ protected async Task Insert_with_output_parameter_and_result_column(bool async, protected async Task Update(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity().UpdateUsingStoredProcedure( nameof(Entity) + "_Update", spb => spb @@ -169,7 +169,7 @@ protected async Task Update(bool async, string createSprocSql) .HasParameter(w => w.Name)), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -191,7 +191,7 @@ protected async Task Update(bool async, string createSprocSql) protected async Task Update_partial(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity().UpdateUsingStoredProcedure( nameof(EntityWithAdditionalProperty) + "_Update", spb => spb .HasOriginalValueParameter(w => w.Id) @@ -199,7 +199,7 @@ protected async Task Update_partial(bool async, string createSprocSql) .HasParameter(w => w.AdditionalProperty)), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new EntityWithAdditionalProperty { Name = "Foo", AdditionalProperty = 8 }; context.Set().Add(entity); @@ -225,7 +225,7 @@ protected async Task Update_partial(bool async, string createSprocSql) protected async Task Update_with_output_parameter_and_rows_affected_result_column(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.AdditionalProperty).HasComputedColumnSql("8"); @@ -240,7 +240,7 @@ protected async Task Update_with_output_parameter_and_rows_affected_result_colum }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new EntityWithAdditionalProperty { Name = "Foo" }; context.Set().Add(entity); @@ -266,7 +266,7 @@ protected async Task Update_with_output_parameter_and_rows_affected_result_colum protected async Task Update_with_output_parameter_and_rows_affected_result_column_concurrency_failure(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.AdditionalProperty).HasComputedColumnSql("8"); @@ -281,13 +281,13 @@ protected async Task Update_with_output_parameter_and_rows_affected_result_colum }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new EntityWithAdditionalProperty { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); context2.Set().Remove(entity2); @@ -308,14 +308,14 @@ protected async Task Update_with_output_parameter_and_rows_affected_result_colum protected async Task Delete(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .DeleteUsingStoredProcedure( nameof(Entity) + "_Delete", spb => spb.HasOriginalValueParameter(w => w.Id)), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -337,7 +337,7 @@ protected async Task Delete(bool async, string createSprocSql) protected async Task Delete_and_insert(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .InsertUsingStoredProcedure( nameof(Entity) + "_Insert", @@ -349,7 +349,7 @@ protected async Task Delete_and_insert(bool async, string createSprocSql) spb => spb.HasOriginalValueParameter(w => w.Id)), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Entity1" }; context.Set().Add(entity1); @@ -373,7 +373,7 @@ protected async Task Delete_and_insert(bool async, string createSprocSql) protected async Task Rows_affected_parameter(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -383,7 +383,7 @@ protected async Task Rows_affected_parameter(bool async, string createSprocSql) .HasRowsAffectedParameter()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -406,7 +406,7 @@ protected async Task Rows_affected_parameter(bool async, string createSprocSql) protected async Task Rows_affected_parameter_and_concurrency_failure(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -416,13 +416,13 @@ protected async Task Rows_affected_parameter_and_concurrency_failure(bool async, .HasRowsAffectedParameter()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); context2.Set().Remove(entity2); @@ -443,7 +443,7 @@ protected async Task Rows_affected_parameter_and_concurrency_failure(bool async, protected async Task Rows_affected_result_column(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -453,7 +453,7 @@ protected async Task Rows_affected_result_column(bool async, string createSprocS .HasRowsAffectedResultColumn()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -476,7 +476,7 @@ protected async Task Rows_affected_result_column(bool async, string createSprocS protected async Task Rows_affected_result_column_and_concurrency_failure(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -486,13 +486,13 @@ protected async Task Rows_affected_result_column_and_concurrency_failure(bool as .HasRowsAffectedResultColumn()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); context2.Set().Remove(entity2); @@ -513,7 +513,7 @@ protected async Task Rows_affected_result_column_and_concurrency_failure(bool as protected async Task Rows_affected_return_value(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -523,7 +523,7 @@ protected async Task Rows_affected_return_value(bool async, string createSprocSq .HasRowsAffectedReturnValue()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -546,7 +546,7 @@ protected async Task Rows_affected_return_value(bool async, string createSprocSq protected async Task Rows_affected_return_value_and_concurrency_failure(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -556,13 +556,13 @@ protected async Task Rows_affected_return_value_and_concurrency_failure(bool asy .HasRowsAffectedReturnValue()), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); context2.Set().Remove(entity2); @@ -583,7 +583,7 @@ protected async Task Rows_affected_return_value_and_concurrency_failure(bool asy protected async Task Store_generated_concurrency_token_as_in_out_parameter(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { ConfigureStoreGeneratedConcurrencyToken(b, "ConcurrencyToken"); @@ -598,13 +598,13 @@ protected async Task Store_generated_concurrency_token_as_in_out_parameter(bool }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); entity2.Name = "Preempted"; @@ -625,7 +625,7 @@ protected async Task Store_generated_concurrency_token_as_in_out_parameter(bool protected async Task Store_generated_concurrency_token_as_two_parameters(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { ConfigureStoreGeneratedConcurrencyToken(b, "ConcurrencyToken"); @@ -644,13 +644,13 @@ protected async Task Store_generated_concurrency_token_as_two_parameters(bool as }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new Entity { Name = "Initial" }; context1.Set().Add(entity1); await context1.SaveChangesAsync(); - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); entity2.Name = "Preempted"; @@ -671,7 +671,7 @@ protected async Task Store_generated_concurrency_token_as_two_parameters(bool as protected async Task User_managed_concurrency_token(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(e => e.AdditionalProperty).IsConcurrencyToken(); @@ -687,7 +687,7 @@ protected async Task User_managed_concurrency_token(bool async, string createSpr }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context1 = contextFactory.CreateContext(); + await using var context1 = contextFactory.CreateDbContext(); var entity1 = new EntityWithAdditionalProperty { @@ -700,7 +700,7 @@ protected async Task User_managed_concurrency_token(bool async, string createSpr entity1.Name = "Updated"; entity1.AdditionalProperty = 9; - await using (var context2 = contextFactory.CreateContext()) + await using (var context2 = contextFactory.CreateDbContext()) { var entity2 = await context2.Set().SingleAsync(w => w.Name == "Initial"); entity2.Name = "Preempted"; @@ -719,7 +719,7 @@ protected async Task User_managed_concurrency_token(bool async, string createSpr protected async Task Original_and_current_value_on_non_concurrency_token(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .UpdateUsingStoredProcedure( nameof(Entity) + "_Update", @@ -729,7 +729,7 @@ protected async Task Original_and_current_value_on_non_concurrency_token(bool as .HasOriginalValueParameter(w => w.Name, pb => pb.HasName("NameOriginal"))), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; @@ -755,7 +755,7 @@ protected async Task Original_and_current_value_on_non_concurrency_token(bool as protected async Task Input_or_output_parameter_with_input(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.Name).IsRequired().ValueGeneratedOnAdd(); @@ -768,7 +768,7 @@ protected async Task Input_or_output_parameter_with_input(bool async, string cre }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity { Name = "Initial" }; context.Set().Add(entity); @@ -788,7 +788,7 @@ protected async Task Input_or_output_parameter_with_input(bool async, string cre protected async Task Input_or_output_parameter_with_output(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity(b => { b.Property(w => w.Name).IsRequired().ValueGeneratedOnAdd(); @@ -801,7 +801,7 @@ protected async Task Input_or_output_parameter_with_output(bool async, string cr }), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = new Entity(); context.Set().Add(entity); @@ -821,7 +821,7 @@ protected async Task Input_or_output_parameter_with_output(bool async, string cr protected async Task Tph(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => { modelBuilder.Entity(); @@ -850,7 +850,7 @@ protected async Task Tph(bool async, string createSprocSql) }, seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity1 = new Child1 { Name = "Child", Child1Property = 8 }; context.Set().Add(entity1); @@ -872,7 +872,7 @@ protected async Task Tph(bool async, string createSprocSql) protected async Task Tpt(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => { modelBuilder.Entity(b => @@ -895,7 +895,7 @@ protected async Task Tpt(bool async, string createSprocSql) }, seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity1 = new Child1 { Name = "Child", Child1Property = 8 }; context.Set().Add(entity1); @@ -917,7 +917,7 @@ protected async Task Tpt(bool async, string createSprocSql) protected async Task Tpt_mixed_sproc_and_non_sproc(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => { modelBuilder.Entity(b => @@ -936,7 +936,7 @@ protected async Task Tpt_mixed_sproc_and_non_sproc(bool async, string createSpro }, seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity1 = new Child1 { Name = "Child", Child1Property = 8 }; context.Set().Add(entity1); @@ -958,7 +958,7 @@ protected async Task Tpt_mixed_sproc_and_non_sproc(bool async, string createSpro protected async Task Tpc(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => { modelBuilder.Entity().UseTpcMappingStrategy(); @@ -974,7 +974,7 @@ protected async Task Tpc(bool async, string createSprocSql) }, seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity1 = new Child1 { Name = "Child", Child1Property = 8 }; context.Set().Add(entity1); @@ -996,7 +996,7 @@ protected async Task Tpc(bool async, string createSprocSql) protected async Task Non_sproc_followed_by_sproc_commands_in_the_same_batch(bool async, string createSprocSql) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( modelBuilder => modelBuilder.Entity() .InsertUsingStoredProcedure( nameof(EntityWithAdditionalProperty) + "_Insert", @@ -1007,7 +1007,7 @@ protected async Task Non_sproc_followed_by_sproc_commands_in_the_same_batch(bool .Property(e => e.AdditionalProperty).IsConcurrencyToken(), seed: ctx => CreateStoredProcedures(ctx, createSprocSql)); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); // Prepare by adding an entity var entity1 = new EntityWithAdditionalProperty { Name = "Entity1", AdditionalProperty = 1 }; diff --git a/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs b/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs index fd1d6d1937a..79982b01579 100644 --- a/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/BulkUpdates/NonSharedModelBulkUpdatesTestBase.cs @@ -8,15 +8,15 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public abstract class NonSharedModelBulkUpdatesTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "NonSharedModelBulkUpdatesTests"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_aggregate_root_when_eager_loaded_owned_collection(bool async) { - var contextFactory = await InitializeAsync(onModelCreating: mb => mb.Entity().Ignore(e => e.OwnedReference)); + var contextFactory = await InitializeNonSharedTest(onModelCreating: mb => mb.Entity().Ignore(e => e.OwnedReference)); await AssertDelete( - async, contextFactory.CreateContext, + async, contextFactory.CreateDbContext, context => context.Set(), rowsAffectedCount: 0); } @@ -25,29 +25,29 @@ await AssertDelete( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_with_owned_collection_and_non_natively_translatable_query(bool async) { - var contextFactory = await InitializeAsync(onModelCreating: mb => mb.Entity().Ignore(e => e.OwnedReference)); + var contextFactory = await InitializeNonSharedTest(onModelCreating: mb => mb.Entity().Ignore(e => e.OwnedReference)); await AssertDelete( - async, contextFactory.CreateContext, + async, contextFactory.CreateDbContext, context => context.Set().OrderBy(o => o.Title).Skip(1), rowsAffectedCount: 0); } [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_aggregate_root_when_table_sharing_with_owned(bool async) { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); await AssertDelete( - async, contextFactory.CreateContext, + async, contextFactory.CreateDbContext, context => context.Set(), rowsAffectedCount: 0); } [ConditionalTheory, MemberData(nameof(IsAsyncData))] // #33937, #33946 public virtual async Task Replace_ColumnExpression_in_column_setter(bool async) { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set().SelectMany(e => e.OwnedCollections), s => s.SetProperty(o => o.Value, "SomeValue"), rowsAffectedCount: 0); @@ -93,7 +93,7 @@ public class OtherReference [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_non_owned_property_on_entity_with_owned(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().OwnsOne(o => o.OwnedReference); @@ -101,7 +101,7 @@ public virtual async Task Update_non_owned_property_on_entity_with_owned(bool as await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set(), s => s.SetProperty(o => o.Title, "SomeValue"), rowsAffectedCount: 0); @@ -110,7 +110,7 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_non_owned_property_on_entity_with_owned2(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().OwnsOne(o => o.OwnedReference); @@ -118,7 +118,7 @@ public virtual async Task Update_non_owned_property_on_entity_with_owned2(bool a await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set(), s => s.SetProperty(o => o.Title, o => o.Title + "_Suffix"), rowsAffectedCount: 0); @@ -127,7 +127,7 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_non_owned_property_on_entity_with_owned_in_join(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().OwnsOne(o => o.OwnedReference); @@ -135,7 +135,7 @@ public virtual async Task Update_non_owned_property_on_entity_with_owned_in_join await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set().Join(ss.Set(), o => o.Id, i => i.Id, (o, i) => new { Outer = o, Inner = i }), s => s.SetProperty(t => t.Outer.Title, "NewValue"), rowsAffectedCount: 0); @@ -144,7 +144,7 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_owned_and_non_owned_properties_with_table_sharing(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().OwnsOne(o => o.OwnedReference); @@ -152,7 +152,7 @@ public virtual async Task Update_owned_and_non_owned_properties_with_table_shari await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Set(), s => s .SetProperty(o => o.Title, o => o.OwnedReference.Number.ToString()) @@ -163,8 +163,8 @@ await AssertUpdate( [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_entity_with_auto_include(bool async) { - var contextFactory = await InitializeAsync(); - await AssertDelete(async, contextFactory.CreateContext, ss => ss.Set(), rowsAffectedCount: 0); + var contextFactory = await InitializeNonSharedTest(); + await AssertDelete(async, contextFactory.CreateDbContext, ss => ss.Set(), rowsAffectedCount: 0); } protected class Context30572(DbContextOptions options) : DbContext(options) @@ -191,9 +191,9 @@ public class Context30572_Dependent [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Delete_predicate_based_on_optional_navigation(bool async) { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); await AssertDelete( - async, contextFactory.CreateContext, + async, contextFactory.CreateDbContext, context => context.Posts.Where(p => p.Blog!.Title!.StartsWith("Arthur")), rowsAffectedCount: 1); } @@ -221,10 +221,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Update_with_alias_uniquification_in_setter_subquery(bool async) { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); await AssertUpdate( async, - contextFactory.CreateContext, + contextFactory.CreateDbContext, ss => ss.Orders.Where(o => o.Id == 1) .Select(o => new { Order = o, Total = o.OrderProducts.Sum(op => op.Amount) }), s => s.SetProperty(x => x.Order.Total, x => x.Total), diff --git a/test/EFCore.Specification.Tests/JsonTypesTestBase.cs b/test/EFCore.Specification.Tests/JsonTypesTestBase.cs index 87b45536ada..f79a154024e 100644 --- a/test/EFCore.Specification.Tests/JsonTypesTestBase.cs +++ b/test/EFCore.Specification.Tests/JsonTypesTestBase.cs @@ -3663,7 +3663,7 @@ protected virtual Task Can_read_and_write_JSON_value( var contextFactory = CreateContextFactory( buildModel, configureConventions: configureConventions); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var property = context.Model.FindEntityType(typeof(TEntity))!.GetProperty(propertyName); @@ -3738,7 +3738,7 @@ protected virtual Task Can_read_and_write_JSON_value( return Task.CompletedTask; } - protected override string StoreName + protected override string NonSharedStoreName => "JsonTypesTest"; protected virtual void AssertElementFacets(IElementType element, Dictionary? facets) diff --git a/test/EFCore.Specification.Tests/MaterializationInterceptionTestBase.cs b/test/EFCore.Specification.Tests/MaterializationInterceptionTestBase.cs index 91853555604..033ee2aeb8d 100644 --- a/test/EFCore.Specification.Tests/MaterializationInterceptionTestBase.cs +++ b/test/EFCore.Specification.Tests/MaterializationInterceptionTestBase.cs @@ -7,7 +7,7 @@ public abstract class MaterializationInterceptionTestBase(NonSharedFix : SingletonInterceptorsTestBase(fixture) where TContext : SingletonInterceptorsTestBase.LibraryContext { - protected override string StoreName + protected override string NonSharedStoreName => "MaterializationInterception"; [ConditionalTheory, ClassData(typeof(DataGenerator))] diff --git a/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs b/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs index 50fc1c2e0c2..ae44b093cdf 100644 --- a/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs +++ b/test/EFCore.Specification.Tests/NonSharedModelTestBase.cs @@ -5,45 +5,38 @@ namespace Microsoft.EntityFrameworkCore; -public abstract class NonSharedModelTestBase : IAsyncLifetime +public abstract class NonSharedModelTestBase(NonSharedFixture fixture) : IAsyncLifetime { public static readonly IEnumerable IsAsyncData = [[false], [true]]; - protected abstract string StoreName { get; } - protected abstract ITestStoreFactory TestStoreFactory { get; } - protected NonSharedFixture? Fixture { get; set; } + protected abstract string NonSharedStoreName { get; } + protected abstract ITestStoreFactory NonSharedTestStoreFactory { get; } + protected NonSharedFixture? NonSharedFixture { get; set; } = fixture; protected virtual ITestOutputHelper? TestOutputHelper { get; set; } private ServiceProvider? _serviceProvider; - protected IServiceProvider ServiceProvider + protected IServiceProvider NonSharedServiceProvider => _serviceProvider ?? throw new InvalidOperationException( $"You must call `await {nameof(InitializeAsync)}(\"DatabaseName\");` at the beginning of the test."); private TestStore? _testStore; - protected TestStore TestStore + protected TestStore NonSharedTestStore => _testStore ?? throw new InvalidOperationException( $"You must call `await {nameof(InitializeAsync)}(\"DatabaseName\");` at the beginning of the test."); private ListLoggerFactory? _listLoggerFactory; - protected ListLoggerFactory ListLoggerFactory - => _listLoggerFactory ??= (ListLoggerFactory)ServiceProvider.GetRequiredService(); - - protected NonSharedModelTestBase() - { - } - - protected NonSharedModelTestBase(NonSharedFixture? fixture) - => Fixture = fixture; + protected virtual ListLoggerFactory ListLoggerFactory + => _listLoggerFactory ??= (ListLoggerFactory)NonSharedServiceProvider.GetRequiredService(); public virtual Task InitializeAsync() => Task.CompletedTask; - protected virtual async Task> InitializeAsync( + protected virtual async Task> InitializeNonSharedTest( Action? onModelCreating = null, Action? onConfiguring = null, Func? addServices = null, @@ -55,12 +48,14 @@ protected virtual async Task> InitializeAsync bool useServiceProvider = true) where TContext : DbContext { - if (Fixture == null && _testStore != null) + if (NonSharedFixture == null && _testStore != null) { await _testStore.DisposeAsync(); - _serviceProvider?.Dispose(); } + _serviceProvider?.Dispose(); + _serviceProvider = null; + var contextFactory = CreateContextFactory( onModelCreating, onConfiguring, @@ -71,7 +66,7 @@ protected virtual async Task> InitializeAsync usePooling, useServiceProvider); - await TestStore.InitializeAsync(_serviceProvider, contextFactory.CreateContext, seed == null ? null : c => seed((TContext)c)); + await NonSharedTestStore.InitializeAsync(_serviceProvider, contextFactory.CreateDbContext, seed == null ? null : c => seed((TContext)c)); ListLoggerFactory.Clear(); @@ -93,21 +88,21 @@ protected virtual ContextFactory CreateContextFactory( if (createTestStore != null) { _testStore = createTestStore(); - Fixture = null; + NonSharedFixture = null; } else { - _testStore = Fixture != null - ? Fixture.GetOrCreateTestStore(CreateTestStore) + _testStore = NonSharedFixture != null + ? NonSharedFixture.GetOrCreateTestStore(CreateTestStore) : CreateTestStore(); } shouldLogCategory ??= _ => false; var services = AddServices( (useServiceProvider - ? TestStoreFactory.AddProviderServices(new ServiceCollection()) + ? NonSharedTestStoreFactory.AddProviderServices(new ServiceCollection()) : new ServiceCollection()) - .AddSingleton(TestStoreFactory.CreateListLoggerFactory(shouldLogCategory))); + .AddSingleton(CreateNonSharedLoggerFactory(shouldLogCategory))); if (onModelCreating != null) { @@ -135,7 +130,7 @@ private DbContextOptionsBuilder ConfigureOptions( DbContextOptionsBuilder optionsBuilder, Action? onConfiguring) { - optionsBuilder = AddOptions(TestStore.AddProviderOptions(optionsBuilder)); + optionsBuilder = AddNonSharedOptions(NonSharedTestStore.AddProviderOptions(optionsBuilder)); if (serviceProvider == null) { optionsBuilder.EnableServiceProviderCaching(false); @@ -149,10 +144,13 @@ private DbContextOptionsBuilder ConfigureOptions( return optionsBuilder; } + protected virtual ILoggerFactory CreateNonSharedLoggerFactory(Func shouldLogCategory) + => NonSharedTestStoreFactory.CreateListLoggerFactory(shouldLogCategory); + protected virtual IServiceCollection AddServices(IServiceCollection serviceCollection) => serviceCollection; - protected virtual DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected virtual DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) => builder .EnableSensitiveDataLogging() .ConfigureWarnings(b => b.Default(WarningBehavior.Throw) @@ -164,7 +162,7 @@ protected virtual DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder bui CoreEventId.MappedNavigationIgnoredWarning)); protected virtual TestStore CreateTestStore() - => TestStoreFactory.Create(StoreName); + => NonSharedTestStoreFactory.Create(NonSharedStoreName); // Called after DisposeAsync public virtual void Dispose() @@ -173,7 +171,7 @@ public virtual void Dispose() public virtual async Task DisposeAsync() { - if (Fixture == null && _testStore != null) + if (NonSharedFixture == null && _testStore != null) { await _testStore.DisposeAsync(); _testStore = null; @@ -185,7 +183,7 @@ public virtual async Task DisposeAsync() _listLoggerFactory = null; } - protected class ContextFactory + protected class ContextFactory : IDbContextFactory where TContext : DbContext { public ContextFactory(IServiceProvider serviceProvider, bool usePooling, TestStore testStore) @@ -208,7 +206,7 @@ public ContextFactory(IServiceProvider serviceProvider, bool usePooling, TestSto public TestStore TestStore { get; } - public virtual TContext CreateContext() + public virtual TContext CreateDbContext() => UsePooling ? PooledContextFactory!.CreateDbContext() : (TContext)ServiceProvider.GetRequiredService(typeof(TContext)); diff --git a/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs index 6134e870fd7..457f9409af1 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocAdvancedMappingsQueryTestBase.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocAdvancedMappingsQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocAdvancedMappingsQueryTests"; #region 9582 @@ -20,8 +20,8 @@ protected override string StoreName [ConditionalFact] public virtual async Task Setting_IsUnicode_generates_unicode_literal_in_SQL() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(xx => xx.Nombre.Contains("lla")).ToList(); } @@ -59,8 +59,8 @@ public class TipoServicio [ConditionalFact] public virtual async Task Projecting_correlated_collection_along_with_non_mapped_property() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using (var context = contextFactory.CreateDbContext()) { var result = context.Blogs.Select(e => new { @@ -70,7 +70,7 @@ public virtual async Task Projecting_correlated_collection_along_with_non_mapped }).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Blogs.Select(e => new { @@ -128,8 +128,8 @@ public class Post [ConditionalFact] public virtual async Task Projection_failing_with_EnumToStringConverter() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = from p in context.Products join c in context.Categories on p.CategoryId equals c.Id into grouping from c in grouping.DefaultIfEmpty() @@ -212,27 +212,27 @@ public enum CategoryStatus [ConditionalFact] public virtual async Task Expression_tree_constructed_via_interface_works() { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var query = Context17276.List(context.RemovableEntities); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Parents .Where(p => EF.Property(EF.Property(p, "RemovableEntity"), "IsRemoved")) .ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.RemovableEntities .Where(p => EF.Property(EF.Property(p, "OwnedEntity"), "OwnedValue") == "Abc") .ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var specification = new Context17276.Specification(1); var entities = context.Set().Where(specification.Criteria).ToList(); @@ -308,8 +308,8 @@ public class Specification(int id) [ConditionalFact] public virtual async Task Double_convert_interface_created_expression_tree() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var expression = Context17794.HasAction17794(Context17794.Actions.Accepted); var query = context.Offers.Where(expression).Count(); @@ -379,9 +379,9 @@ public class OfferAction [ConditionalFact] public virtual async Task Casts_are_removed_from_expression_tree_when_redundant() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var queryBase = (IQueryable)context.MockEntities; var id = 1; @@ -390,7 +390,7 @@ public virtual async Task Casts_are_removed_from_expression_tree_when_redundant( Assert.Equal(1, query.Id); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var queryBase = (IQueryable)context.MockEntities; var query = queryBase.Cast().Count(); @@ -398,7 +398,7 @@ public virtual async Task Casts_are_removed_from_expression_tree_when_redundant( Assert.Equal(3, query); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var queryBase = (IQueryable)context.MockEntities; var id = 1; @@ -455,8 +455,8 @@ public class MockEntity : IDomainEntity [ConditionalFact] public virtual async Task Can_query_hierarchy_with_non_nullable_property_on_derived() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Businesses.ToList(); Assert.Equal(3, query.Count); } @@ -511,7 +511,7 @@ public enum BusinessType //[InlineData(0, " (Scale = 0)")] //https://github.com/dotnet/SqlClient/issues/1380 cause this test to fail, not EF public virtual async Task Query_generates_correct_datetime2_parameter_definition(int? fractionalSeconds, string postfix) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: modelBuilder => { if (fractionalSeconds.HasValue) @@ -521,7 +521,7 @@ public virtual async Task Query_generates_correct_datetime2_parameter_definition }); var parameter = new DateTime(2021, 11, 12, 13, 14, 15).AddTicks(1234567); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); _ = context.Entities.Where(x => x.DateTime == parameter).Select(e => e.DateTime).FirstOrDefault(); } @@ -530,7 +530,7 @@ public virtual async Task Query_generates_correct_datetime2_parameter_definition //[InlineData(0, " (Scale = 0)")] //https://github.com/dotnet/SqlClient/issues/1380 cause this test to fail, not EF public virtual async Task Query_generates_correct_datetimeoffset_parameter_definition(int? fractionalSeconds, string postfix) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: modelBuilder => { if (fractionalSeconds.HasValue) @@ -540,7 +540,7 @@ public virtual async Task Query_generates_correct_datetimeoffset_parameter_defin }); var parameter = new DateTimeOffset(new DateTime(2021, 11, 12, 13, 14, 15).AddTicks(1234567), TimeSpan.FromHours(10)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); _ = context.Entities.Where(x => x.DateTimeOffset == parameter).Select(e => e.DateTimeOffset).FirstOrDefault(); } @@ -549,7 +549,7 @@ public virtual async Task Query_generates_correct_datetimeoffset_parameter_defin //[InlineData(0, " (Scale = 0)")] //https://github.com/dotnet/SqlClient/issues/1380 cause this test to fail, not EF public virtual async Task Query_generates_correct_timespan_parameter_definition(int? fractionalSeconds, string postfix) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: modelBuilder => { if (fractionalSeconds.HasValue) @@ -559,7 +559,7 @@ public virtual async Task Query_generates_correct_timespan_parameter_definition( }); var parameter = TimeSpan.Parse("12:34:56.7890123", CultureInfo.InvariantCulture); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); _ = context.Entities.Where(x => x.TimeSpan == parameter).Select(e => e.TimeSpan).FirstOrDefault(); } @@ -587,8 +587,8 @@ public virtual Task Hierarchy_query_with_abstract_type_sibling(bool async) public virtual async Task Hierarchy_query_with_abstract_type_sibling_helper(bool async, Action onModelCreating) { - var contextFactory = await InitializeAsync(onModelCreating: onModelCreating, seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(onModelCreating: onModelCreating, seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Animals.OfType().Where(a => a.Species.StartsWith("F")); var result = async ? await query.ToListAsync() @@ -676,8 +676,8 @@ public class Dog : Pet [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Projecting_property_with_converter_with_closure(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Books.Select(x => x.PublishDate); @@ -688,8 +688,8 @@ public virtual async Task Projecting_property_with_converter_with_closure(bool a [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Projecting_expression_with_converter_with_closure(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Books .GroupBy(t => t.Id) @@ -702,8 +702,8 @@ public virtual async Task Projecting_expression_with_converter_with_closure(bool [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Projecting_property_with_converter_without_closure(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Books .GroupBy(t => t.Id) diff --git a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs index e336dd34498..5f7faf6978d 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs @@ -12,7 +12,7 @@ public abstract class AdHocComplexTypeQueryTestBase(NonSharedFixture fixture) [ConditionalFact] public virtual async Task Complex_type_equals_parameter_with_nested_types_with_property_of_same_name() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: context => { context.AddRange( @@ -28,7 +28,7 @@ public virtual async Task Complex_type_equals_parameter_with_nested_types_with_p return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var container = new Context33449.ComplexContainer { @@ -82,9 +82,9 @@ public class ComplexContainee2 [ConditionalFact] public virtual async Task Projecting_complex_property_does_not_auto_include_owned_types() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); _ = await context.Set().Select(x => x.Complex).ToListAsync(); } @@ -126,7 +126,7 @@ public class OwnedType [ConditionalFact] public virtual async Task Optional_complex_type_with_discriminator() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: context => { context.AddRange( @@ -146,7 +146,7 @@ public virtual async Task Optional_complex_type_with_discriminator() return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var complexTypeNull = await context.Set().SingleAsync(b => b.AllOptionalsComplexType == null); Assert.Null(complexTypeNull.AllOptionalsComplexType); @@ -180,7 +180,7 @@ public class AllOptionalsComplexType [ConditionalFact] public virtual async Task Non_optional_complex_type_with_all_nullable_properties() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: context => { context.Add( @@ -194,7 +194,7 @@ public virtual async Task Non_optional_complex_type_with_all_nullable_properties return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entity = await context.Set().SingleAsync(); @@ -228,7 +228,7 @@ public class ComplexTypeWithAllNulls [ConditionalFact] public virtual async Task Nullable_complex_type_with_discriminator_and_shadow_property() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: context => { context.Add( @@ -242,7 +242,7 @@ public virtual async Task Nullable_complex_type_with_discriminator_and_shadow_pr return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var entities = await context.Set().ToArrayAsync(); @@ -282,6 +282,6 @@ public class OptionalComplexProperty #endregion Issue37337 - protected override string StoreName + protected override string NonSharedStoreName => "AdHocComplexTypeQueryTest"; } diff --git a/test/EFCore.Specification.Tests/Query/AdHocJsonQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocJsonQueryTestBase.cs index 93b77bc7971..8371d13018c 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocJsonQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocJsonQueryTestBase.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocJsonQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocJsonQueryTests"; protected virtual void ClearLog() @@ -22,12 +22,12 @@ protected virtual void ConfigureWarnings(WarningsConfigurationBuilder builder) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_root_with_missing_scalars(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id < 4); @@ -52,12 +52,12 @@ public virtual async Task Project_root_with_missing_scalars(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_top_level_json_entity_with_missing_scalars(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id < 4).Select(x => new { @@ -88,12 +88,12 @@ public virtual async Task Project_top_level_json_entity_with_missing_scalars(boo [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_nested_json_entity_with_missing_scalars(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id < 4).Select(x => new { @@ -118,12 +118,12 @@ public virtual async Task Project_nested_json_entity_with_missing_scalars(bool a [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_top_level_entity_with_null_value_required_scalars(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 4).Select(x => new { @@ -142,12 +142,12 @@ public virtual async Task Project_top_level_entity_with_null_value_required_scal [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_root_entity_with_missing_required_navigation(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 5).AsNoTracking(); @@ -165,12 +165,12 @@ public virtual async Task Project_root_entity_with_missing_required_navigation(b [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_missing_required_navigation(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 5).Select(x => x.RequiredReference.NestedRequiredReference) .AsNoTracking(); @@ -187,12 +187,12 @@ public virtual async Task Project_missing_required_navigation(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_root_entity_with_null_required_navigation(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 6).AsNoTracking(); @@ -210,12 +210,12 @@ public virtual async Task Project_root_entity_with_null_required_navigation(bool [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_null_required_navigation(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 6).Select(x => x.RequiredReference).AsNoTracking(); @@ -231,12 +231,12 @@ public virtual async Task Project_null_required_navigation(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_missing_required_scalar(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set() .Where(x => x.Id == 2) @@ -252,12 +252,12 @@ public virtual async Task Project_missing_required_scalar(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Project_null_required_scalar(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating21006, seed: Seed21006); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set() .Where(x => x.Id == 4) @@ -407,12 +407,12 @@ public class JsonEntityNested [ConditionalFact] public virtual async Task Optional_json_properties_materialized_as_null_when_the_element_in_json_is_not_present() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating29219, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed29219); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Id == 3); var result = await query.SingleAsync(); @@ -424,12 +424,12 @@ public virtual async Task Optional_json_properties_materialized_as_null_when_the [ConditionalFact] public virtual async Task Can_project_nullable_json_property_when_the_element_in_json_is_not_present() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating29219, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed29219); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().OrderBy(x => x.Id).Select(x => x.Reference.NullableScalar); var result = await query.ToListAsync(); @@ -496,12 +496,12 @@ public class MyJsonEntity [ConditionalFact] public virtual async Task Accessing_missing_navigation_works() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating30028, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed30028); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var result = await context.Set().OrderBy(x => x.Id).ToListAsync(); Assert.Equal(4, result.Count); Assert.NotNull(result[0].Json.Collection); @@ -524,12 +524,12 @@ public virtual async Task Accessing_missing_navigation_works() [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Missing_navigation_works_with_deduplication(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating30028, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed30028); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var queryable = context.Set().OrderBy(x => x.Id).Select(x => new { x, @@ -620,12 +620,12 @@ public class MyJsonLeafEntity [ConditionalFact] public virtual async Task Contains_on_nested_collection_with_init_only_navigation() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), onModelCreating: OnModelCreating32310, seed: Seed32310); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var query = context.Set() .Where(u => u.Visits.DaysVisited.Contains(new DateOnly(2023, 1, 1))); @@ -673,12 +673,12 @@ public class Visits [ConditionalFact] public virtual async Task Project_json_with_no_properties() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating32939, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed32939); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); await context.Set().ToListAsync(); } @@ -723,12 +723,12 @@ public class JsonFieldOnly [ConditionalFact] public virtual async Task Query_with_nested_json_collection_mapped_to_private_field_via_IReadOnlyList() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreating33046, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: Seed33046); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = await context.Set().ToListAsync(); Assert.Equal(1, query.Count); } @@ -783,17 +783,17 @@ public class SubRound [ConditionalFact] public virtual async Task Project_entity_with_json_null_values() { - var contextFactory = await InitializeAsync(seed: Seed34960, onModelCreating: OnModelCreating34960); + var contextFactory = await InitializeNonSharedTest(seed: Seed34960, onModelCreating: OnModelCreating34960); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = await context.Entities.ToListAsync(); } [ConditionalFact] public virtual async Task Try_project_collection_but_JSON_is_entity() { - var contextFactory = await InitializeAsync(seed: Seed34960, onModelCreating: OnModelCreating34960); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed34960, onModelCreating: OnModelCreating34960); + using var context = contextFactory.CreateDbContext(); await context.Junk.AsNoTracking().Where(x => x.Id == 1).Select(x => x.Collection).FirstOrDefaultAsync(); } @@ -801,8 +801,8 @@ public virtual async Task Try_project_collection_but_JSON_is_entity() [ConditionalFact] public virtual async Task Try_project_reference_but_JSON_is_collection() { - var contextFactory = await InitializeAsync(seed: Seed34960, onModelCreating: OnModelCreating34960); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed34960, onModelCreating: OnModelCreating34960); + using var context = contextFactory.CreateDbContext(); await context.Junk.AsNoTracking().Where(x => x.Id == 2).Select(x => x.Reference).FirstOrDefaultAsync(); } @@ -976,12 +976,12 @@ protected virtual async Task Seed34960(Context34960 ctx) [ConditionalFact] public virtual async Task Project_json_array_of_primitives_on_reference() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().OrderBy(x => x.Id) .Select(x => new { x.Reference.IntArray, x.Reference.ListOfString }); @@ -997,12 +997,12 @@ public virtual async Task Project_json_array_of_primitives_on_reference() [ConditionalFact(Skip = "Issue #32611")] public virtual async Task Project_json_array_of_primitives_on_collection() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().OrderBy(x => x.Id) .Select(x => new { x.Collection[0].IntArray, x.Collection[1].ListOfString }); @@ -1018,12 +1018,12 @@ public virtual async Task Project_json_array_of_primitives_on_collection() [ConditionalFact] public virtual async Task Project_element_of_json_array_of_primitives() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().OrderBy(x => x.Id).Select(x => new { ArrayElement = x.Reference.IntArray[0], ListElement = x.Reference.ListOfString[1] }); var result = await query.ToListAsync(); @@ -1032,12 +1032,12 @@ public virtual async Task Project_element_of_json_array_of_primitives() [ConditionalFact] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives1() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Reference.IntArray[0] == 1); var result = await query.ToListAsync(); @@ -1048,12 +1048,12 @@ public virtual async Task Predicate_based_on_element_of_json_array_of_primitives [ConditionalFact] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives2() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Where(x => x.Reference.ListOfString[1] == "Bar"); var result = await query.ToListAsync(); @@ -1064,12 +1064,12 @@ public virtual async Task Predicate_based_on_element_of_json_array_of_primitives [ConditionalFact, MemberData(nameof(IsAsyncData))] public virtual async Task Predicate_based_on_element_of_json_array_of_primitives3() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingArrayOfPrimitives, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedArrayOfPrimitives); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .Where(x => x.Reference.IntArray.AsQueryable().ElementAt(0) == 1 || x.Reference.ListOfString.AsQueryable().ElementAt(1) == "Bar") @@ -1158,12 +1158,12 @@ public class MyJsonEntity [ConditionalFact] public virtual async Task Junk_in_json_basic_tracking() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingJunkInJson, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedJunkInJson); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = await query.ToListAsync(); @@ -1179,12 +1179,12 @@ public virtual async Task Junk_in_json_basic_tracking() [ConditionalFact] public virtual async Task Junk_in_json_basic_no_tracking() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingJunkInJson, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedJunkInJson); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().AsNoTracking(); var result = await query.ToListAsync(); @@ -1280,12 +1280,12 @@ public class MyJsonEntityWithCtorNested(DateTime doB) [ConditionalFact] public virtual async Task Tricky_buffering_basic() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingTrickyBuffering, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedTrickyBuffering); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = await query.ToListAsync(); @@ -1339,12 +1339,12 @@ public class MyJsonEntityNested [ConditionalFact] public virtual async Task Shadow_properties_basic_tracking() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingShadowProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = await query.ToListAsync(); @@ -1374,12 +1374,12 @@ public virtual async Task Shadow_properties_basic_tracking() [ConditionalFact] public virtual async Task Shadow_properties_basic_no_tracking() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingShadowProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().AsNoTracking(); var result = await query.ToListAsync(); @@ -1393,12 +1393,12 @@ public virtual async Task Shadow_properties_basic_no_tracking() [ConditionalFact] public virtual async Task Project_shadow_properties_from_json_entity() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingShadowProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedShadowProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Select(x => new { ShadowString = EF.Property(x.Reference, "ShadowString"), @@ -1475,7 +1475,7 @@ public class MyJsonEntityWithCtor(string name) [ConditionalFact] public virtual async Task Project_proxies_entity_with_json() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingLazyLoadingProxies, seed: SeedLazyLoadingProxies, onConfiguring: b => @@ -1485,7 +1485,7 @@ public virtual async Task Project_proxies_entity_with_json() }, addServices: AddServicesLazyLoadingProxies); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = await query.ToListAsync(); @@ -1572,12 +1572,12 @@ public class MyJsonEntity [ConditionalFact] public virtual async Task Not_ICollection_basic_projection() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingNotICollection, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedNotICollection); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = await query.ToListAsync(); @@ -1628,12 +1628,12 @@ public class MyJsonNestedEntity [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_duplicated_navigations(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var baseline = await query.SingleAsync(x => x.Scenario == "baseline"); var dupNavs = await query.SingleAsync(x => x.Scenario == "duplicated navigations"); @@ -1663,12 +1663,12 @@ public virtual async Task Bad_json_properties_duplicated_navigations(bool noTrac [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_duplicated_scalars(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var baseline = await query.SingleAsync(x => x.Scenario == "baseline"); @@ -1698,12 +1698,12 @@ public virtual async Task Bad_json_properties_duplicated_scalars(bool noTracking [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_empty_navigations(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var emptyNavs = await query.SingleAsync(x => x.Scenario == "empty navigation property names"); @@ -1727,12 +1727,12 @@ public virtual async Task Bad_json_properties_empty_navigations(bool noTracking) [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_empty_scalars(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var emptyNavs = await query.SingleAsync(x => x.Scenario == "empty scalar property names"); @@ -1760,12 +1760,12 @@ public virtual async Task Bad_json_properties_empty_scalars(bool noTracking) [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_null_navigations(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var _ = await query.SingleAsync(x => x.Scenario == "null navigation property names"); } @@ -1773,12 +1773,12 @@ public virtual async Task Bad_json_properties_null_navigations(bool noTracking) [ConditionalTheory, InlineData(true), InlineData(false)] public virtual async Task Bad_json_properties_null_scalars(bool noTracking) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: OnModelCreatingBadJsonProperties, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedBadJsonProperties); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = noTracking ? context.Entities.AsNoTracking() : context.Entities; var _ = await query.SingleAsync(x => x.Scenario == "null scalar property names"); } diff --git a/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs index 67d8a1595bf..c6a4dd2038f 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocManyToManyQueryTestBase.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; public abstract class AdHocManyToManyQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocManyToManyQueryTests"; protected virtual void ClearLog() @@ -19,8 +19,8 @@ protected virtual void ClearLog() [ConditionalFact] public virtual async Task SelectMany_with_collection_selector_having_subquery() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var users = (from user in context.Users from organisation in context.Organisations.Where(o => o.OrganisationUsers.Any()).DefaultIfEmpty() select new { UserId = user.Id, OrgId = organisation.Id }).ToList(); @@ -82,10 +82,10 @@ public class OrganisationUser [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Many_to_many_load_works_when_join_entity_has_custom_key(bool async) { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); int id; - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var m = new ManyM_DB(); var n = new ManyN_DB(); @@ -99,7 +99,7 @@ public virtual async Task Many_to_many_load_works_when_join_entity_has_custom_ke ClearLog(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var m = context.Find(id); @@ -121,7 +121,7 @@ public virtual async Task Many_to_many_load_works_when_join_entity_has_custom_ke id = m.ManyN_DB.Single().Id; } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var n = context.Find(id); diff --git a/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs index 4d75e2b6b4a..1799b60855c 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocMiscellaneousQueryTestBase.cs @@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore; public abstract class AdHocMiscellaneousQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocMiscellaneousQueryTests"; #region 603 @@ -20,21 +20,21 @@ protected override string StoreName [ConditionalFact] public virtual async Task First_FirstOrDefault_ix_async() { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var product = await context.Products.OrderBy(p => p.Id).FirstAsync(); context.Products.Remove(product); await context.SaveChangesAsync(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Products.Add(new Context603.Product { Name = "Product 1" }); await context.SaveChangesAsync(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var product = await context.Products.OrderBy(p => p.Id).FirstOrDefaultAsync(); context.Products.Remove(product); @@ -66,8 +66,8 @@ public class Product [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task LeftJoin_with_missing_key_values_on_both_sides(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var results = context.Customers @@ -185,9 +185,9 @@ public class Postcode [ConditionalFact] public virtual async Task Shadow_property_with_inheritance() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { // can_query_base_type_when_derived_types_contain_shadow_properties var query = context.Contacts.ToList(); @@ -197,7 +197,7 @@ public virtual async Task Shadow_property_with_inheritance() Assert.Single(query.OfType()); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { // can_include_dependent_to_principal_navigation_of_derived_type_with_shadow_fk var query = context.Contacts.OfType().Include(e => e.ServiceOperator) @@ -207,7 +207,7 @@ public virtual async Task Shadow_property_with_inheritance() Assert.NotNull(query[0].ServiceOperator); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { // can_project_shadow_property_using_ef_property var query = context.Contacts.OfType() @@ -294,13 +294,13 @@ public class ServiceOperator [ConditionalFact] public virtual async Task Inlined_dbcontext_is_not_leaking() { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var entities = context.Blogs.Select(b => context.ClientMethod(b)).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Assert.Throws(() => context.RunQuery()); } @@ -330,16 +330,16 @@ public class Blog [ConditionalFact] public virtual async Task Discriminator_type_is_handled_correctly() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var ctx = contextFactory.CreateContext()) + using (var ctx = contextFactory.CreateDbContext()) { var query = ctx.Products.OfType().ToList(); Assert.Single(query); } - using (var ctx = contextFactory.CreateContext()) + using (var ctx = contextFactory.CreateDbContext()) { var query = ctx.Products.Where(p => p is Context7359.SpecialProduct).ToList(); @@ -385,8 +385,8 @@ public class SpecialProduct : Product; [ConditionalFact] public virtual async Task New_instances_in_projection_are_not_shared_across_results() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var list = context.Posts.Select(p => new Context7983.PostDTO().From(p)).ToList(); Assert.Equal(3, list.Count); @@ -451,15 +451,15 @@ public PostDTO From(Post post) [ConditionalFact] public virtual async Task Enum_has_flag_applies_explicit_cast_for_constant() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Entities.Where(e => e.Permission.HasFlag(Context8538.Permission.READ_WRITE)).ToList(); Assert.Single(query); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Entities.Where(e => e.PermissionShort.HasFlag(Context8538.PermissionShort.READ_WRITE)).ToList(); Assert.Single(query); @@ -469,15 +469,15 @@ public virtual async Task Enum_has_flag_applies_explicit_cast_for_constant() [ConditionalFact] public virtual async Task Enum_has_flag_does_not_apply_explicit_cast_for_non_constant() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Entities.Where(e => e.Permission.HasFlag(e.Permission)).ToList(); Assert.Equal(3, query.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Entities.Where(e => e.PermissionByte.HasFlag(e.PermissionByte)).ToList(); Assert.Equal(3, query.Count); @@ -555,8 +555,8 @@ public enum Permission : long [ConditionalFact] public virtual async Task Variable_from_closure_is_parametrized() { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { context.Cache.Compact(1); @@ -569,7 +569,7 @@ public virtual async Task Variable_from_closure_is_parametrized() Assert.Equal(2, context.Cache.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Cache.Compact(1); @@ -586,7 +586,7 @@ public virtual async Task Variable_from_closure_is_parametrized() Assert.Equal(2, context.Cache.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Cache.Compact(1); @@ -609,8 +609,8 @@ public virtual async Task Variable_from_closure_is_parametrized() [ConditionalFact] public virtual async Task Relational_command_cache_creates_new_entry_when_parameter_nullability_changes() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Cache.Compact(1); var name = "A"; @@ -626,8 +626,8 @@ public virtual async Task Relational_command_cache_creates_new_entry_when_parame [ConditionalFact] public virtual async Task Query_cache_entries_are_evicted_as_necessary() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Cache.Compact(1); Assert.Equal(0, context.Cache.Count); @@ -659,9 +659,9 @@ public virtual async Task Explicitly_compiled_query_does_not_add_cache_entry() parameter); var query = EF.CompileQuery((Context8909 context) => context.Set().SingleOrDefault(predicate)); - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.Cache.Compact(1); Assert.Equal(0, context.Cache.Count); @@ -704,8 +704,8 @@ public class Entity [ConditionalFact] public virtual async Task Conditional_expression_with_conditions_does_not_collapse_if_nullable_bool() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Carts.Select(t => new { Processing = t.Configuration != null ? !t.Configuration.Processed : (bool?)null }) .ToList(); @@ -751,8 +751,8 @@ public class Configuration [ConditionalFact] public virtual async Task QueryBuffer_requirement_is_computed_when_querying_base_type_while_derived_type_has_shadow_prop() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Bases.ToList(); var derived1 = Assert.Single(query); @@ -802,8 +802,8 @@ public class Stuff [ConditionalFact] public virtual async Task Average_with_cast() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var prices = context.Prices.ToList(); Assert.Equal(prices.Average(e => e.Price), context.Prices.Average(e => e.Price)); @@ -901,8 +901,8 @@ public class PriceEntity [ConditionalFact] public virtual async Task Parameterless_ctor_on_inner_DTO_gets_called_for_every_row() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var results = context.Entities.Select(x => new Context12274.OuterDTO { @@ -955,9 +955,9 @@ public class InnerDTO; [ConditionalFact] public virtual async Task Union_and_insert_works_correctly_together() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var id1 = 1; var id2 = 2; @@ -1006,8 +1006,8 @@ public class Table2 [ConditionalFact] public virtual async Task Repeated_parameters_in_generated_query_sql() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var k = 1; var a = context.Autos.Where(e => e.Id == k).First(); var b = context.Autos.Where(e => e.Id == k + 1).First(); @@ -1063,9 +1063,9 @@ public class EqualAuto [ConditionalFact] public virtual async Task Operators_combine_nullability_of_entity_shapers() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Expression> leftKeySelector = x => x.forkey; Expression> rightKeySelector = y => y.forkey; @@ -1093,7 +1093,7 @@ public virtual async Task Operators_combine_nullability_of_entity_shapers() Assert.Equal(3, query.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Expression> leftKeySelector = x => x.forkey; Expression> rightKeySelector = y => y.forkey; @@ -1121,7 +1121,7 @@ public virtual async Task Operators_combine_nullability_of_entity_shapers() Assert.Equal(3, query.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Expression> leftKeySelector = x => x.forkey; Expression> rightKeySelector = y => y.forkey; @@ -1148,7 +1148,7 @@ public virtual async Task Operators_combine_nullability_of_entity_shapers() Assert.Single(query); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Expression> leftKeySelector = x => x.forkey; Expression> rightKeySelector = y => y.forkey; @@ -1250,8 +1250,8 @@ public class B [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Comparing_enum_casted_to_byte_with_int_parameter(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var bitterTaste = Context21770.Taste.Bitter; var query = context.IceCreams.Where(i => i.Taste == (byte)bitterTaste); @@ -1265,8 +1265,8 @@ public virtual async Task Comparing_enum_casted_to_byte_with_int_parameter(bool [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Comparing_enum_casted_to_byte_with_int_constant(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.IceCreams.Where(i => i.Taste == (byte)Context21770.Taste.Bitter); var bitterIceCreams = async @@ -1279,8 +1279,8 @@ public virtual async Task Comparing_enum_casted_to_byte_with_int_constant(bool a [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Comparing_byte_column_to_enum_in_vb_creating_double_cast(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); Expression> memberAccess = i => i.Taste; var predicate = Expression.Lambda>( Expression.Equal( @@ -1299,8 +1299,8 @@ public virtual async Task Comparing_byte_column_to_enum_in_vb_creating_double_ca [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Null_check_removal_in_ternary_maintain_appropriate_cast(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = from f in context.Foods select new { Bar = f.Taste != null ? (Context21770.Taste)f.Taste : (Context21770.Taste?)null }; @@ -1374,9 +1374,9 @@ public class Food [ConditionalFact(Skip = "Issue #34727 - flaky test")] public virtual async Task SaveChangesAsync_accepts_changes_with_ConfigureAwait_true() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var observableThing = new Context22841.ObservableThing(); using var trackingSynchronizationContext = new SingleThreadSynchronizationContext(); @@ -1443,8 +1443,8 @@ public int Id [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Bool_discriminator_column_works(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Authors.Include(e => e.Blog); @@ -1509,8 +1509,8 @@ public PhotoBlog() [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Unwrap_convert_node_over_projection_when_translating_contains_over_subquery(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var currentUserId = 1; @@ -1533,8 +1533,8 @@ public virtual async Task Unwrap_convert_node_over_projection_when_translating_c [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Unwrap_convert_node_over_projection_when_translating_contains_over_subquery_2(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var currentUserId = 1; @@ -1557,8 +1557,8 @@ public virtual async Task Unwrap_convert_node_over_projection_when_translating_c [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Unwrap_convert_node_over_projection_when_translating_contains_over_subquery_3(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var currentUserId = 1; @@ -1626,8 +1626,8 @@ public class Membership [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task GroupBy_aggregate_on_right_side_of_join(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var orderId = 123456; @@ -1671,8 +1671,8 @@ public class OrderItem [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Enum_with_value_converter_matching_take_value(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var orderItemType = Context26472.OrderItemType.MyType1; var query = context.Orders.Where(x => x.Items.Any()).OrderBy(e => e.Id).Take(1) .Select(e => e.Id) @@ -1729,8 +1729,8 @@ public enum OrderItemType [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task GroupBy_Aggregate_over_navigations_repeated(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context .Set() @@ -1753,8 +1753,8 @@ public virtual async Task GroupBy_Aggregate_over_navigations_repeated(bool async [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Aggregate_over_subquery_in_group_by_projection(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); Expression> someFilterFromOutside = x => x.Number != "A1"; @@ -1884,8 +1884,8 @@ public class TimeSheet [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Aggregate_over_subquery_in_group_by_projection_2(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = from t in context.Tables group t.Id by t.Value @@ -1903,8 +1903,8 @@ into tg [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Group_by_aggregate_in_subquery_projection_after_group_by(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = from t in context.Tables group t.Id by t.Value @@ -1944,8 +1944,8 @@ public class Table [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Subquery_first_member_compared_to_null(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Parents .Where(p => p.Children.Any(c => c.SomeNullableDateTime == null) @@ -1967,8 +1967,8 @@ public virtual async Task Subquery_first_member_compared_to_null(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task SelectMany_where_Select(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Parents .SelectMany(p => p.Children @@ -2020,8 +2020,8 @@ public class Child [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Flattened_GroupJoin_on_interface_generic(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var entitySet = context.Parents.AsQueryable(); var query = from p in entitySet join c in context.Set() @@ -2072,8 +2072,8 @@ public class Child [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Pushdown_does_not_add_grouping_key_to_projection_when_distinct_is_applied(bool async) { - var contextFactory = await InitializeAsync(); - using var db = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var db = contextFactory.CreateDbContext(); var queryResults = (from i in db.IndexDatas.Where(a => a.Parcel == "some condition") .Select(a => new Context28039.SearchResult { ParcelNumber = a.Parcel, RowId = a.RowId }) @@ -2134,8 +2134,8 @@ public class SearchResult [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Filter_on_nested_DTO_with_interface_gets_simplified_correctly(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Customers .Select(m => new Context31961.CustomerDto @@ -2260,8 +2260,8 @@ public class CompanyDto : ICompanyDto [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Coalesce_in_conditional_with_value_conversion(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .OrderBy(e => e.Id) diff --git a/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs index bd8be0f302e..af35e366c7a 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocNavigationsQueryTestBase.cs @@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocNavigationsQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocNavigationsQueryTests"; #region 3409 @@ -21,9 +21,9 @@ protected override string StoreName [ConditionalFact] public virtual async Task ThenInclude_with_interface_navigations() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var results = context.Parents .Include(p => p.ChildCollection) @@ -35,7 +35,7 @@ public virtual async Task ThenInclude_with_interface_navigations() Assert.Equal(2, results[0].ChildCollection.Single().SelfReferenceCollection.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var results = context.Children .Select(c => new { c.SelfReferenceBackNavigation, c.SelfReferenceBackNavigation.ParentBackNavigation }) @@ -46,7 +46,7 @@ public virtual async Task ThenInclude_with_interface_navigations() Assert.Equal(2, results.Count(c => c.ParentBackNavigation != null)); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var results = context.Children .Select(c => new @@ -65,7 +65,7 @@ public virtual async Task ThenInclude_with_interface_navigations() Assert.Equal(2, results.Count(c => c.ParentBackNavigationB != null)); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var results = context.Children .Include(c => c.SelfReferenceBackNavigation) @@ -158,9 +158,9 @@ public class Child : IChild [ConditionalFact] public virtual async Task Customer_collections_materialize_properly() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var query1 = ctx.Customers.Select(c => c.Orders1); var result1 = query1.ToList(); @@ -300,9 +300,9 @@ public MyInvalidCollection(int argument) [ConditionalFact] public virtual async Task Reference_include_on_derived_type_with_sibling_works() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Proposals.OfType().Include(l => l.LeaveType).ToList(); @@ -357,9 +357,9 @@ public class ProposalLeaveType [ConditionalFact] public virtual async Task Include_collection_optional_reference_collection() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = await context.People.OfType() .Include(m => m.Students) @@ -371,7 +371,7 @@ public virtual async Task Include_collection_optional_reference_collection() Assert.True(result.All(r => r.Students.Count > 0)); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = await context.Set() .Include(m => m.Family.Members) @@ -479,13 +479,13 @@ public class PersonFamily9038 [ConditionalFact] public virtual async Task Include_with_order_by_on_interface_key() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using (var context = contextFactory.CreateDbContext()) { var query = context.Parents.Include(p => p.Children).OrderBy(p => p.Id).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Parents.OrderBy(p => p.Id).Select(p => p.Children.ToList()).ToList(); } @@ -538,8 +538,8 @@ public class Child10635 : IEntity10635 [ConditionalFact] public virtual async Task Collection_without_setter_materialized_correctly() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query1 = context.Blogs .Select(b => new { @@ -654,9 +654,9 @@ public class CustomCollection : List; [ConditionalFact] public virtual async Task Include_collection_works_when_defined_on_intermediate_type() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Schools.Include(s => ((Context11944.ElementarySchool)s).Students); var result = query.ToList(); @@ -665,7 +665,7 @@ public virtual async Task Include_collection_works_when_defined_on_intermediate_ Assert.Equal(2, result.OfType().Single().Students.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Schools.Select(s => ((Context11944.ElementarySchool)s).Students.Where(ss => true).ToList()); var result = query.ToList(); @@ -724,15 +724,15 @@ public class ElementarySchool : PrimarySchool; [ConditionalFact] public virtual async Task Let_multiple_references_with_reference_to_outer() { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var users = (from a in context.Activities let cs = context.CompetitionSeasons.First(s => s.StartDate <= a.DateTime && a.DateTime < s.EndDate) select new { cs.Id, Points = a.ActivityType.Points.Where(p => p.CompetitionSeason == cs) }).ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var users = context.Activities .Select(a => new @@ -808,9 +808,9 @@ public class Activity [ConditionalFact] public virtual async Task Include_collection_with_OfType_base() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Employees .Include(i => i.Devices) @@ -823,7 +823,7 @@ public virtual async Task Include_collection_with_OfType_base() Assert.Equal(2, employee.Devices.Count); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Employees .Select(e => e.Devices.Where(d => d.Device != "foo").Cast()) @@ -885,8 +885,8 @@ public class EmployeeDevice : IEmployeeDevice [ConditionalFact] public virtual async Task Correlated_collection_correctly_associates_entities_with_byte_array_keys() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = from blog in context.Blogs select new { blog.Name, Comments = blog.Comments.Select(u => new { u.Id }).ToArray() }; var result = query.ToList(); @@ -929,10 +929,10 @@ public class Comment [ConditionalFact] public virtual async Task Can_ignore_invalid_include_path_error() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: o => o.ConfigureWarnings(x => x.Ignore(CoreEventId.InvalidIncludePathError))); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var result = context.Set().Include("SubB").ToList(); } @@ -981,9 +981,9 @@ public class SubB [ConditionalFact] public virtual async Task SelectMany_and_collection_in_projection_in_FirstOrDefault() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var referenceId = "a"; var customerId = new Guid("1115c816-6c4c-4016-94df-d8b60a22ffa1"); var query = context.Orders @@ -1059,8 +1059,8 @@ public class IdentityDocumentImage [ConditionalFact] public virtual async Task Using_explicit_interface_implementation_as_navigation_works() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); Expression> projection = b => new Context21768.BookViewModel { @@ -1182,8 +1182,8 @@ public enum IllustrationState [ConditionalFact] public virtual async Task Cycles_in_auto_include() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using (var context = contextFactory.CreateDbContext()) { var principals = context.Set().ToList(); Assert.Single(principals); @@ -1196,7 +1196,7 @@ public virtual async Task Cycles_in_auto_include() Assert.NotNull(dependents[0].Principal.Dependent); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var principals = context.Set().ToList(); Assert.Single(principals); @@ -1210,7 +1210,7 @@ public virtual async Task Cycles_in_auto_include() Assert.True(dependents.All(e => e.Principal.Dependents.All(i => i.Principal != null))); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Assert.Equal( CoreStrings.AutoIncludeNavigationCycle("'PrincipalManyToMany.Dependents', 'DependentManyToMany.Principals'"), @@ -1224,7 +1224,7 @@ public virtual async Task Cycles_in_auto_include() context.Set().IgnoreAutoIncludes().ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Assert.Equal( CoreStrings.AutoIncludeNavigationCycle("'CycleA.Bs', 'CycleB.C', 'CycleC.As'"), @@ -1344,9 +1344,9 @@ public class CycleC [ConditionalFact] public virtual async Task Walking_back_include_tree_is_not_allowed_1() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set() .Include(p => p.ManyDependents) @@ -1365,9 +1365,9 @@ public virtual async Task Walking_back_include_tree_is_not_allowed_1() [ConditionalFact] public virtual async Task Walking_back_include_tree_is_not_allowed_2() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set().Include(p => p.SingleDependent.Principal.ManyDependents); @@ -1384,9 +1384,9 @@ public virtual async Task Walking_back_include_tree_is_not_allowed_2() [ConditionalFact] public virtual async Task Walking_back_include_tree_is_not_allowed_3() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { // This does not warn because after round-tripping from one-to-many from dependent side, the number of dependents could be larger. var query = context.Set() @@ -1399,9 +1399,9 @@ public virtual async Task Walking_back_include_tree_is_not_allowed_3() [ConditionalFact] public virtual async Task Walking_back_include_tree_is_not_allowed_4() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set().Include(p => p.ManyDependent.SingleDependent.Principal); @@ -1452,9 +1452,9 @@ public class SingleDependent [ConditionalFact] public virtual async Task Projection_with_multiple_includes_and_subquery_with_set_operation() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var id = 1; var person = await context.Persons .Include(p => p.Images) @@ -1592,8 +1592,8 @@ public class MovieEntity [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Count_member_over_IReadOnlyCollection_works(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Authors .Select(a => new { BooksCount = a.Books.Count }); diff --git a/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs index 7d1436f1568..352bc6ac97b 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocQueryFiltersQueryTestBase.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocQueryFiltersQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "AdHocQueryFiltersQueryTests"; #region 8576 @@ -16,8 +16,8 @@ protected override string StoreName [ConditionalFact] public virtual async Task Named_query_filters() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities.ToList(); Assert.Single(result); @@ -26,8 +26,8 @@ public virtual async Task Named_query_filters() [ConditionalFact] public virtual async Task Named_query_filters_ignore_some() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities .IgnoreQueryFilters(["ActiveFilter", "NameFilter"]) .ToList(); @@ -38,13 +38,13 @@ public virtual async Task Named_query_filters_ignore_some() public virtual async Task Named_query_filters_caching() { var cacheLog = new List(); - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync(), onConfiguring: builder => + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync(), onConfiguring: builder => { builder.EnableSensitiveDataLogging(); builder.LogTo(cacheLog.Add, filter: (eventid, _) => eventid.Name == CoreEventId.QueryCompilationStarting.Name); }); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); _ = context.Entities .IgnoreQueryFilters(["ActiveFilter", "NameFilter"]) @@ -62,8 +62,8 @@ public virtual async Task Named_query_filters_caching() [ConditionalFact] public virtual async Task Named_query_filters_ignore_all() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities .IgnoreQueryFilters() @@ -74,8 +74,8 @@ public virtual async Task Named_query_filters_ignore_all() [ConditionalFact] public virtual async Task Named_query_filters_anonymous() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities .ToList(); @@ -85,8 +85,8 @@ public virtual async Task Named_query_filters_anonymous() [ConditionalFact] public virtual async Task Named_query_filters_anonymous_ignore() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities .IgnoreQueryFilters() @@ -99,15 +99,15 @@ public virtual async Task Named_query_filters_combined() { var exception = await Assert.ThrowsAsync(async () - => await InitializeAsync(seed: c => c.SeedAsync())); + => await InitializeNonSharedTest(seed: c => c.SeedAsync())); Assert.Equal(exception.Message, CoreStrings.AnonymousAndNamedFiltersCombined); } [ConditionalFact] public virtual async Task Named_query_filters_overwriting() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities.ToList(); Assert.Single(result); @@ -116,8 +116,8 @@ public virtual async Task Named_query_filters_overwriting() [ConditionalFact] public virtual async Task Named_query_filters_removing() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities.ToList(); Assert.Equal(2, result.Count); @@ -190,8 +190,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalFact] public virtual async Task Query_filter_with_contains_evaluates_correctly() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Entities.ToList(); Assert.Single(result); } @@ -227,9 +227,9 @@ public class MyEntity10295 [ConditionalFact] public virtual async Task MultiContext_query_filter_test() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { Assert.Empty(context.Blogs.ToList()); @@ -277,8 +277,8 @@ protected class FilterContext10301(DbContextOptions options) : FilterContextBase [ConditionalFact] public virtual async Task Weak_entities_with_query_filter_subquery_flattening() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var result = context.Definitions.Any(); Assert.False(result); @@ -338,8 +338,8 @@ public class Definition12170 [ConditionalFact] public virtual async Task Query_filter_with_pk_fk_optimization() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); context.Entities.Select(s => new Context13517.EntityDto13517 { @@ -401,15 +401,15 @@ public class RefEntityDto13517 [ConditionalFact] public virtual async Task Self_reference_in_query_filter_works() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.EntitiesWithQueryFilterSelfReference.Where(e => e.Name != "Foo"); var result = query.ToList(); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.EntitiesReferencingEntityWithQueryFilterSelfReference.Where(e => e.Name != "Foo"); var result = query.ToList(); @@ -496,8 +496,8 @@ public class EntityWithQueryFilterCycle17253_3 [ConditionalFact] public virtual async Task Invoke_inside_query_filter_gets_correctly_evaluated_during_translation() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); context.TenantId = 1; var query1 = context.Entities.ToList(); @@ -572,8 +572,8 @@ public class MyEntity18510 [ConditionalFact] public virtual async Task Query_filter_with_null_constant() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var people = context.People.ToList(); } @@ -605,8 +605,8 @@ public class User18759 [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task IsDeleted_query_filter_with_conversion_to_int_works(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Suppliers.Include(s => s.Location).OrderBy(s => s.Name); @@ -686,8 +686,8 @@ protected class Location [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Group_by_multiple_aggregate_joining_different_tables(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Parents .GroupBy(x => new { }) @@ -711,8 +711,8 @@ public virtual async Task Group_by_multiple_aggregate_joining_different_tables(b [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Group_by_multiple_aggregate_joining_different_tables_with_query_filter(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Parents .GroupBy(x => new { }) @@ -786,8 +786,8 @@ public class ChildFilter2 [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Query_filter_with_context_accessor_with_constant(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var data = async ? await context.Set().ToListAsync() diff --git a/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs index e78ba572820..2dbff0af02f 100644 --- a/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore; public abstract class OwnedEntityQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "OwnedEntityQueryTests"; #region 9202 @@ -17,9 +17,9 @@ protected override string StoreName [ConditionalFact] public virtual async Task Include_collection_for_entity_with_owned_type_works() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Movies.Include(m => m.Cast); var result = query.ToList(); @@ -30,7 +30,7 @@ public virtual async Task Include_collection_for_entity_with_owned_type_works() Assert.True(result[0].Cast.All(a => a.Details != null)); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Movies.Include("Cast"); var result = query.ToList(); @@ -108,8 +108,8 @@ public class Details [ConditionalFact] public virtual async Task Multilevel_owned_entities_determine_correct_nullability() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); await context.AddAsync(new Context13079.BaseEntity()); await context.SaveChangesAsync(); } @@ -152,9 +152,9 @@ public class OwnedSubData [ConditionalFact] public virtual async Task Correlated_subquery_with_owned_navigation_being_compared_to_null_works() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var partners = context.Partners .Select(x => new @@ -230,8 +230,8 @@ public class AddressTurnovers [ConditionalFact] public virtual async Task Owned_entity_multiple_level_in_aggregate() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var aggregate = context.Set().OrderByDescending(e => e.Id).FirstOrDefault(); Assert.Equal(10, aggregate.FirstValueObject.SecondValueObjects[0].FourthValueObject.FifthValueObjects[0].AnyValue); Assert.Equal( @@ -362,9 +362,9 @@ public class FifthValueObject [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Projecting_correlated_collection_property_for_owned_entity(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Warehouses.Select(x => new Context18582.WarehouseModel { WarehouseCode = x.WarehouseCode, DestinationCountryCodes = x.DestinationCountries.Select(c => c.CountryCode).ToArray() @@ -436,8 +436,8 @@ public class WarehouseModel [ConditionalFact] public virtual async Task Accessing_scalar_property_in_derived_type_projection_does_not_load_owned_navigations() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.BaseEntities .Select(b => context.OtherEntities.Where(o => o.OtherEntityData == ((Context19138.SubEntity)b).Data).FirstOrDefault()) .ToList(); @@ -497,8 +497,8 @@ public class OtherEntity [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Multiple_single_result_in_projection_containing_owned_types(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Entities.AsNoTracking().Select(e => new { e.Id, @@ -573,9 +573,9 @@ public class Owned [ConditionalFact] public virtual async Task Can_auto_include_navigation_from_model() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Parents.AsNoTracking().ToList(); var result = Assert.Single(query); @@ -587,7 +587,7 @@ public virtual async Task Can_auto_include_navigation_from_model() Assert.Single(result.SkipOtherSide); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Parents.AsNoTracking().IgnoreAutoIncludes().ToList(); var result = Assert.Single(query); @@ -688,8 +688,8 @@ public class Collection [ConditionalFact] public virtual async Task Nested_owned_required_dependents_are_materialized() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Set().ToList(); var result = Assert.Single(query); Assert.NotNull(result.Contact); @@ -749,8 +749,8 @@ public class Address [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task OwnsMany_correlated_projection(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var results = await context.Contacts.Select(contact => new Context22089.ContactDto { @@ -802,8 +802,8 @@ public class NameDto [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Projecting_owned_collection_and_aggregate(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.Set() .Select(b => new Context24133.BlogDto { diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 514a3bb7cc7..6b8a4dda9e8 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs @@ -5,8 +5,6 @@ using System.Collections.Frozen; using System.Collections.Immutable; -using static System.Linq.Expressions.Expression; - namespace Microsoft.EntityFrameworkCore.Query; public abstract class PrimitiveCollectionsQueryTestBase(TFixture fixture) : QueryTestBase(fixture) diff --git a/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs index 4f80180df00..f5677a30fce 100644 --- a/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/QueryFixtureBase.cs @@ -41,9 +41,6 @@ public TestStore GetOrCreateNonSharedTestStore(Func createTestStore) public ITestStoreFactory GetTestStoreFactory() => TestStoreFactory; - public TestStore NonSharedTestStore - => _nonSharedTestStore ?? throw new InvalidOperationException("No non-shared test store has been created, call GetOrCreateNonSharedTestStore() first."); - public override async Task DisposeAsync() { await base.DisposeAsync(); diff --git a/test/EFCore.Specification.Tests/Query/QueryTestBase.cs b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs index 80ec0dff9da..71dc6a8ebf3 100644 --- a/test/EFCore.Specification.Tests/Query/QueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/QueryTestBase.cs @@ -5,12 +5,13 @@ namespace Microsoft.EntityFrameworkCore.Query; -public abstract class QueryTestBase : IClassFixture, IAsyncLifetime +public abstract class QueryTestBase : NonSharedModelTestBase, IClassFixture where TFixture : class, IQueryFixtureBase, new() { private readonly Lazy _queryAsserterCache; protected QueryTestBase(TFixture fixture) + : base(new QueryNonSharedFixtureAdapter(fixture)) { Fixture = fixture; @@ -34,8 +35,6 @@ protected virtual Expression RewriteServerQueryExpression(Expression serverQuery protected virtual Expression RewriteExpectedQueryExpression(Expression expectedQueryExpression) => new ExpectedQueryRewritingVisitor().Visit(expectedQueryExpression); - public static readonly IEnumerable IsAsyncData = [[false], [true]]; - public static readonly IEnumerable TrackingData = [ [QueryTrackingBehavior.TrackAll], @@ -1186,110 +1185,25 @@ protected Task AssertAverage( #region Non-shared test support - private ServiceProvider? _nonSharedServiceProvider; - - protected virtual string NonSharedStoreName + protected override string NonSharedStoreName => Fixture.StoreName + "_NonShared"; - public virtual Task InitializeAsync() - => Task.CompletedTask; - - public virtual async Task DisposeAsync() - { - _nonSharedServiceProvider?.Dispose(); - _nonSharedServiceProvider = null; - } - - protected virtual async Task> InitializeNonSharedTest( - Action? onModelCreating = null, - Action? onConfiguring = null, - Func? addServices = null, - Action? configureConventions = null, - Func? seed = null, - bool usePooling = true, - bool useServiceProvider = true) - where TContext : DbContext - { - _nonSharedServiceProvider?.Dispose(); - _nonSharedServiceProvider = null; - - var testStoreFactory = Fixture.GetTestStoreFactory(); - var testStore = Fixture.GetOrCreateNonSharedTestStore(() => testStoreFactory.Create(NonSharedStoreName)); - - IServiceCollection services = new ServiceCollection(); - - if (useServiceProvider) - { - testStoreFactory.AddProviderServices(services); - } - - services = services.AddSingleton(new NonDisposingLoggerFactoryWrapper(Fixture.ListLoggerFactory)); - - if (onModelCreating != null) - { - services = services.AddSingleton(TestModelSource.GetFactory(onModelCreating, configureConventions)); - } - - addServices?.Invoke(services); - - services = usePooling - ? services.AddPooledDbContextFactory( - typeof(TContext), (s, b) => ConfigureNonSharedOptions(useServiceProvider ? s : null, b, onConfiguring, testStore)) - : services.AddDbContext( - typeof(TContext), - (s, b) => ConfigureNonSharedOptions(useServiceProvider ? s : null, b, onConfiguring, testStore), - ServiceLifetime.Transient, - ServiceLifetime.Singleton); + protected override ITestStoreFactory NonSharedTestStoreFactory + => Fixture.GetTestStoreFactory(); - _nonSharedServiceProvider = services.BuildServiceProvider(validateScopes: true); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => Fixture.AddOptions(base.AddNonSharedOptions(builder)); - var contextFactory = new ContextFactory(_nonSharedServiceProvider, usePooling); + protected override ILoggerFactory CreateNonSharedLoggerFactory(Func shouldLogCategory) + => new NonDisposingLoggerFactoryWrapper(Fixture.ListLoggerFactory); - await testStore.InitializeAsync( - _nonSharedServiceProvider, contextFactory.CreateDbContext, seed == null ? null : c => seed((TContext)c)); - - Fixture.ListLoggerFactory.Clear(); - - return contextFactory; - - DbContextOptionsBuilder ConfigureNonSharedOptions( - IServiceProvider? serviceProvider, - DbContextOptionsBuilder optionsBuilder, - Action? onConfiguring, - TestStore testStore) - { - optionsBuilder = Fixture.AddOptions(testStore.AddProviderOptions(optionsBuilder)) - .ConfigureWarnings(w => w.Ignore( - CoreEventId.MappedEntityTypeIgnoredWarning, - CoreEventId.MappedPropertyIgnoredWarning, - CoreEventId.MappedNavigationIgnoredWarning)); - if (serviceProvider == null) - { - optionsBuilder.EnableServiceProviderCaching(false); - } - else - { - optionsBuilder.UseInternalServiceProvider(serviceProvider); - } - - onConfiguring?.Invoke(optionsBuilder); - return optionsBuilder; - } - } + protected override ListLoggerFactory ListLoggerFactory + => Fixture.ListLoggerFactory; - private sealed class ContextFactory(IServiceProvider serviceProvider, bool usePooling) - : IDbContextFactory - where TContext : DbContext + private sealed class QueryNonSharedFixtureAdapter(IQueryFixtureBase fixture) : NonSharedFixture { - private IDbContextFactory? PooledContextFactory { get; } - = usePooling - ? (IDbContextFactory)serviceProvider.GetRequiredService(typeof(IDbContextFactory)) - : null; - - public TContext CreateDbContext() - => usePooling - ? PooledContextFactory!.CreateDbContext() - : (TContext)serviceProvider.GetRequiredService(typeof(TContext)); + public override TestStore GetOrCreateTestStore(Func createTestStore) + => fixture.GetOrCreateNonSharedTestStore(createTestStore); } private sealed class NonDisposingLoggerFactoryWrapper(ILoggerFactory inner) : ILoggerFactory diff --git a/test/EFCore.Specification.Tests/Query/SharedTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/SharedTypeQueryTestBase.cs index 64cd1979516..639c4849f42 100644 --- a/test/EFCore.Specification.Tests/Query/SharedTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/SharedTypeQueryTestBase.cs @@ -7,16 +7,16 @@ namespace Microsoft.EntityFrameworkCore; public abstract class SharedTypeQueryTestBase(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "SharedTypeQueryTests"; [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Can_use_shared_type_entity_type_in_query_filter(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set(); var result = async ? await query.ToListAsync() diff --git a/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs b/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs index 3e3308dc9d0..38084cfa33b 100644 --- a/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs +++ b/test/EFCore.Specification.Tests/Scaffolding/CompiledModelTestBase.cs @@ -1989,7 +1989,7 @@ public IEnumerable? RefTypeEnumerable protected abstract TestHelpers TestHelpers { get; } - protected override string StoreName + protected override string NonSharedStoreName => "CompiledModelTest"; private string _filePath = ""; @@ -2070,7 +2070,7 @@ protected virtual Task Test( onConfiguring, addServices, skipValidation: skipValidation); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var model = context.GetService().Model; options ??= new CompiledModelCodeGenerationOptions { ForNativeAot = true }; @@ -2117,7 +2117,7 @@ protected virtual Task Test( if (useContext != null) { - await TestStore.InitializeAsync(ServiceProvider, contextFactory.CreateContext); + await NonSharedTestStore.InitializeAsync(NonSharedServiceProvider, contextFactory.CreateDbContext); ListLoggerFactory.Clear(); using var compiledModelContext = CreateContextFactory( @@ -2127,7 +2127,7 @@ protected virtual Task Test( options.UseModel(compiledModel); }, addServices: addServices) - .CreateContext(); + .CreateDbContext(); await useContext(compiledModelContext); } diff --git a/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs b/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs index 3f19ea6aa2f..4b8fd6eb3ab 100644 --- a/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs +++ b/test/EFCore.Specification.Tests/SharedStoreFixtureBase.cs @@ -46,14 +46,7 @@ public ListLoggerFactory ListLoggerFactory public virtual async Task InitializeAsync() { - if (RecreateStore) - { - _testStore = TestStoreFactory.Create(StoreName); - } - else - { - _testStore = TestStoreFactory.GetOrCreate(StoreName); - } + _testStore = RecreateStore ? TestStoreFactory.Create(StoreName) : TestStoreFactory.GetOrCreate(StoreName); var services = AddServices(TestStoreFactory.AddProviderServices(new ServiceCollection())); services = UsePooling diff --git a/test/EFCore.Specification.Tests/SingletonInterceptorsTestBase.cs b/test/EFCore.Specification.Tests/SingletonInterceptorsTestBase.cs index 5db3b578f45..338a5c33054 100644 --- a/test/EFCore.Specification.Tests/SingletonInterceptorsTestBase.cs +++ b/test/EFCore.Specification.Tests/SingletonInterceptorsTestBase.cs @@ -66,13 +66,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public async Task CreateContext(IEnumerable interceptors, bool inject, bool usePooling) { - var contextFactory = await base.InitializeAsync( + var contextFactory = await base.InitializeNonSharedTest( onConfiguring: inject ? null : o => o.AddInterceptors(interceptors), addServices: inject ? s => InjectInterceptors(s, interceptors) : null, usePooling: usePooling, useServiceProvider: inject); - return contextFactory.CreateContext(); + return contextFactory.CreateDbContext(); } protected virtual IServiceCollection InjectInterceptors( diff --git a/test/EFCore.Specification.Tests/TestUtilities/NonSharedFixture.cs b/test/EFCore.Specification.Tests/TestUtilities/NonSharedFixture.cs index 767fb705baa..7da2959b1ba 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/NonSharedFixture.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/NonSharedFixture.cs @@ -7,16 +7,12 @@ public class NonSharedFixture : IAsyncLifetime { private TestStore? _testStore; - public virtual TestStore GetOrCreateTestStore(Func createTestStore) - => _testStore ??= createTestStore(); - - public virtual void Dispose() - { - } - public Task InitializeAsync() => Task.CompletedTask; + public virtual TestStore GetOrCreateTestStore(Func createTestStore) + => _testStore ??= createTestStore(); + public virtual async Task DisposeAsync() { if (_testStore != null) diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs index 79db8e7e787..e76944c94ec 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public class NonSharedModelBulkUpdatesSqlServerTest(NonSharedFixture fixture) : NonSharedModelBulkUpdatesRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; [ConditionalFact] diff --git a/test/EFCore.SqlServer.FunctionalTests/EntitySplittingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/EntitySplittingSqlServerTest.cs index fd6fdaf4931..ba6cf82cae6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EntitySplittingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/EntitySplittingSqlServerTest.cs @@ -91,6 +91,6 @@ FROM [MeterReadings] AS [m] """); } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; } diff --git a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs index e60d378ccb4..df473fe0ecc 100644 --- a/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/JsonTypesSqlServerTestBase.cs @@ -11,12 +11,12 @@ public override Task Can_read_write_collection_of_fixed_length_string_JSON_value public override Task Can_read_write_collection_of_ASCII_string_JSON_values(object? storeType) => base.Can_read_write_collection_of_ASCII_string_JSON_values("varchar(max)"); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) { - builder = base.AddOptions(builder) + builder = base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w.Ignore(SqlServerEventId.DecimalTypeDefaultWarning)); new SqlServerDbContextOptionsBuilder(builder).UseNetTopologySuite(); return builder; diff --git a/test/EFCore.SqlServer.FunctionalTests/MaterializationInterceptionSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/MaterializationInterceptionSqlServerTest.cs index 1c3e72036f4..5ec9ae22a91 100644 --- a/test/EFCore.SqlServer.FunctionalTests/MaterializationInterceptionSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/MaterializationInterceptionSqlServerTest.cs @@ -18,6 +18,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) #pragma warning restore EF8001 } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs index 1b791445302..a63a4b035e5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocAdvancedMappingsQuerySqlServerTest(NonSharedFixture fixture) : AdHocAdvancedMappingsQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; public override async Task Setting_IsUnicode_generates_unicode_literal_in_SQL() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs index 3f7ba207e1f..de51ef8ec48 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs @@ -72,7 +72,7 @@ FROM [BlogsView] AS [b] [ConditionalFact] public virtual async Task Complex_type_equality_with_non_default_type_mapping() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: context => { context.AddRange( @@ -83,7 +83,7 @@ public virtual async Task Complex_type_equality_with_non_default_type_mapping() return context.SaveChangesAsync(); }); - await using var context = contextFactory.CreateContext(); + await using var context = contextFactory.CreateDbContext(); var count = await context.Set() .CountAsync(b => b.ComplexThing == new Context36837.ComplexThing { DateTime = new DateTime(2020, 1, 1, 1, 1, 1, 999, 999) }); @@ -117,6 +117,6 @@ public class ComplexThing #endregion 36837 - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs index 29b25af1e88..2e1cb8eb454 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerJsonTypeTest.cs @@ -60,7 +60,7 @@ public override Task Try_project_reference_but_JSON_is_collection() public override Task Read_enum_property_with_legacy_values(bool async) => Assert.ThrowsAsync(() => base.Read_enum_property_with_legacy_values_core(async)); - protected override string StoreName + protected override string NonSharedStoreName => "AdHocJsonQueryJsonTypeTest"; protected override string JsonColumnType diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs index be176d627fb..123a5a2228e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocJsonQuerySqlServerTestBase.cs @@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public abstract class AdHocJsonQuerySqlServerTestBase(NonSharedFixture fixture) : AdHocJsonQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected void AssertSql(params string[] expected) @@ -481,12 +481,12 @@ INSERT INTO [Entities] ([Id], [Scenario], [OptionalReference], [RequiredReferenc protected virtual async Task Read_enum_property_with_legacy_values_core(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: BuildModelEnumLegacyValues, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedEnumLegacyValues); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Set().Select(x => new { @@ -509,13 +509,13 @@ protected virtual async Task Read_enum_property_with_legacy_values_core(bool asy [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Read_json_entity_with_enum_properties_with_legacy_values(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: BuildModelEnumLegacyValues, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedEnumLegacyValues, shouldLogCategory: c => c == DbLoggerCategory.Query.Name); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set().Select(x => x.Reference).AsNoTracking(); @@ -549,13 +549,13 @@ public virtual async Task Read_json_entity_with_enum_properties_with_legacy_valu [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Read_json_entity_collection_with_enum_properties_with_legacy_values(bool async) { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: BuildModelEnumLegacyValues, onConfiguring: b => b.ConfigureWarnings(ConfigureWarnings), seed: SeedEnumLegacyValues, shouldLogCategory: c => c == DbLoggerCategory.Query.Name); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Set().Select(x => x.Collection).AsNoTracking(); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocManyToManyQuerySqlServerTest.cs index 536d70fb0be..521ab49a063 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocManyToManyQuerySqlServerTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocManyToManyQuerySqlServerTest(NonSharedFixture fixture) : AdHocManyToManyQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; public override async Task SelectMany_with_collection_selector_having_subquery() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs index 3b3a4766630..0dd131f150b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocMiscellaneousQuerySqlServerTest(NonSharedFixture fixture) : AdHocMiscellaneousQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected override DbContextOptionsBuilder SetParameterizedCollectionMode( @@ -40,14 +40,14 @@ INSERT ZeroKey VALUES (NULL) [ConditionalFact] public virtual async Task Include_group_join_is_per_query_context() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), - createTestStore: () => SqlServerTestStore.Create(StoreName, multipleActiveResultSets: true)); + createTestStore: () => SqlServerTestStore.Create(NonSharedStoreName, multipleActiveResultSets: true)); Parallel.For( 0, 10, i => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).ToList(); Assert.Equal(198, result.Count); @@ -56,7 +56,7 @@ public virtual async Task Include_group_join_is_per_query_context() Parallel.For( 0, 10, i => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).Include(x => x.Comments).ToList(); Assert.Equal(198, result.Count); @@ -65,7 +65,7 @@ public virtual async Task Include_group_join_is_per_query_context() Parallel.For( 0, 10, i => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).ThenInclude(b => b.Author).ToList(); Assert.Equal(198, result.Count); @@ -75,14 +75,14 @@ public virtual async Task Include_group_join_is_per_query_context() [ConditionalFact] public virtual async Task Include_group_join_is_per_query_context_async() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), - createTestStore: () => SqlServerTestStore.Create(StoreName, multipleActiveResultSets: true)); + createTestStore: () => SqlServerTestStore.Create(NonSharedStoreName, multipleActiveResultSets: true)); await Parallel.ForAsync( 0, 10, async (i, ct) => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = await ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).ToListAsync(); Assert.Equal(198, result.Count); @@ -91,7 +91,7 @@ await Parallel.ForAsync( await Parallel.ForAsync( 0, 10, async (i, ct) => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = await ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).Include(x => x.Comments) .ToListAsync(); @@ -101,7 +101,7 @@ await Parallel.ForAsync( await Parallel.ForAsync( 0, 10, async (i, ct) => { - using var ctx = contextFactory.CreateContext(); + using var ctx = contextFactory.CreateDbContext(); var result = await ctx.Posts.Where(x => x.Blog.Id > 1).Include(x => x.Blog).ThenInclude(b => b.Author) .ToListAsync(); @@ -162,9 +162,9 @@ public class Comment [ConditionalFact] public virtual async Task Select_nested_projection() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var customers = context.Customers .Select(c => new { Customer = c, CustomerAgain = Context8864.Get(context, c.Id) }) @@ -232,9 +232,9 @@ public class Customer [ConditionalFact] public async Task Default_schema_applied_when_no_function_schema() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var result = context.Widgets.Where(w => w.Val == 1).Select(w => Context9214.AddOne(w.Val)).Single(); @@ -248,7 +248,7 @@ FROM [foo].[Widgets] AS [w] """); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { ClearLog(); var result = context.Widgets.Where(w => w.Val == 1).Select(w => Context9214.AddTwo(w.Val)).Single(); @@ -331,9 +331,9 @@ public class Widget9214 [ConditionalFact] public virtual async Task From_sql_gets_value_of_out_parameter_in_stored_procedure() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var valueParam = new SqlParameter { @@ -403,9 +403,9 @@ public class Blog9277 [ConditionalFact] public virtual async Task Batch_insert_with_sqlvariant_different_types() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { context.AddRange( new Context12482.BaseEntity { Value = 10.0999 }, @@ -461,8 +461,8 @@ public class BaseEntity [ConditionalFact] public virtual async Task Projecting_entity_with_value_converter_and_include_works() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Parents.Include(p => p.Child).OrderBy(e => e.Id).FirstOrDefault(); AssertSql( @@ -477,8 +477,8 @@ ORDER BY [p].[Id] [ConditionalFact] public virtual async Task Projecting_column_with_value_converter_of_ulong_byte_array() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var result = context.Parents.OrderBy(e => e.Id).Select(p => (ulong?)p.Child.ULongRowVersion).FirstOrDefault(); AssertSql( @@ -539,8 +539,8 @@ public class Child12518 [ConditionalFact] public virtual async Task DateTime_Contains_with_smalldatetime_generates_correct_literal() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var testDateList = new List { new(2018, 10, 07) }; var findRecordsWithDateInList = context.ReproEntity .Where(a => testDateList.Contains(a.MyTime)) @@ -589,9 +589,9 @@ protected class ReproEntity13118 [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Where_equals_DateTime_Now(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Dates.Where(d => d.DateTime2_2 == DateTime.Now || d.DateTime2_7 == DateTime.Now || d.DateTime == DateTime.Now @@ -614,9 +614,9 @@ FROM [Dates] AS [d] [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Where_not_equals_DateTime_Now(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Dates.Where(d => d.DateTime2_2 != DateTime.Now && d.DateTime2_7 != DateTime.Now && d.DateTime != DateTime.Now @@ -639,9 +639,9 @@ FROM [Dates] AS [d] [ConditionalTheory, InlineData(false), InlineData(true)] public async Task Where_equals_new_DateTime(bool async) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Dates.Where(d => d.SmallDateTime == new DateTime(1970, 9, 3, 12, 0, 0) && d.DateTime == new DateTime(1971, 9, 3, 12, 0, 10, 220) && d.DateTime2 == new DateTime(1972, 9, 3, 12, 0, 10, 333) @@ -686,9 +686,9 @@ public async Task Where_contains_DateTime_literals(bool async) new DateTime(1980, 9, 3, 12, 0, 10, 222) }; - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Dates.Where(d => dateTimes.Contains(d.SmallDateTime) && dateTimes.Contains(d.DateTime) && dateTimes.Contains(d.DateTime2) @@ -1006,9 +1006,9 @@ public class DatesAndPrunes14095 [ConditionalTheory, InlineData(false), InlineData(true)] public virtual async Task Nested_queries_does_not_cause_concurrency_exception_sync(bool tracking) { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Repos.OrderBy(r => r.Id).Where(r => r.Id > 0); query = tracking ? query.AsTracking() : query.AsNoTracking(); @@ -1021,7 +1021,7 @@ public virtual async Task Nested_queries_does_not_cause_concurrency_exception_sy } } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = context.Repos.OrderBy(r => r.Id).Where(r => r.Id > 0); query = tracking ? query.AsTracking() : query.AsNoTracking(); @@ -1106,9 +1106,9 @@ public class Repo [ConditionalFact] public virtual async Task From_sql_expression_compares_correctly() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { var query = from t1 in context.Tests.FromSql( $"Select * from Tests Where Type = {Context19206.TestType19206.Unit}") @@ -1174,11 +1174,11 @@ public enum TestType19206 [ConditionalFact] public virtual async Task Thread_safety_in_relational_command_cache() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onConfiguring: options => ((IDbContextOptionsBuilderInfrastructure)options).AddOrUpdateExtension( options.Options.FindExtension() .WithConnection(null) - .WithConnectionString(SqlServerTestStore.CreateConnectionString(StoreName)))); + .WithConnectionString(SqlServerTestStore.CreateConnectionString(NonSharedStoreName)))); var ids = new[] { 1, 2, 3 }; @@ -1186,7 +1186,7 @@ public virtual async Task Thread_safety_in_relational_command_cache() 0, 100, i => { - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var query = context.Lists.Where(l => !l.IsDeleted && ids.Contains(l.Id)).ToList(); }); } @@ -1214,12 +1214,12 @@ public class List [ConditionalFact, SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public virtual async Task Can_query_point_with_buffered_data_reader() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), onConfiguring: o => new SqlServerDbContextOptionsBuilder(o).UseNetTopologySuite(), addServices: c => c.AddEntityFrameworkSqlServerNetTopologySuite()); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); var testUser = context.Locations.FirstOrDefault(x => x.Name == "My Location"); Assert.NotNull(testUser); @@ -1285,8 +1285,8 @@ public class Location [ConditionalFact] public virtual async Task Subquery_take_SelectMany_with_TVF() { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); context.Database.ExecuteSqlRaw( """ @@ -1393,8 +1393,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Muliple_occurrences_of_FromSql_in_group_by_aggregate(bool async) { - var contextFactory = await InitializeAsync(); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(); + using var context = contextFactory.CreateDbContext(); var query = context.DemoEntities .FromSqlRaw("SELECT * FROM DemoEntities WHERE Id = {0}", new SqlParameter { Value = 1 }) .Select(e => e.Id); @@ -1446,8 +1446,8 @@ protected class DemoEntity [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task TemporalAsOf_with_json_basic_query(bool async) { - var contextFactory = await InitializeAsync(seed: x => x.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: x => x.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Entities.TemporalAsOf(new DateTime(2010, 1, 1)); var result = async @@ -1468,8 +1468,8 @@ public virtual async Task TemporalAsOf_with_json_basic_query(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task TemporalAll_with_json_basic_query(bool async) { - var contextFactory = await InitializeAsync(seed: x => x.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: x => x.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Entities.TemporalAll(); var result = async @@ -1490,8 +1490,8 @@ FROM [Entities] FOR SYSTEM_TIME ALL AS [e] [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task TemporalAsOf_project_json_entity_reference(bool async) { - var contextFactory = await InitializeAsync(seed: x => x.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: x => x.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Entities.TemporalAsOf(new DateTime(2010, 1, 1)).Select(x => x.Reference); var result = async @@ -1511,8 +1511,8 @@ public virtual async Task TemporalAsOf_project_json_entity_reference(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task TemporalAsOf_project_json_entity_collection(bool async) { - var contextFactory = await InitializeAsync(seed: x => x.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: x => x.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Entities.TemporalAsOf(new DateTime(2010, 1, 1)).Select(x => x.Collection); var result = async @@ -2628,9 +2628,9 @@ FROM [TestEntities] AS [t] [ConditionalFact] public virtual async Task SqlFragment_within_GroupBy_subquery_pushdown() { - var contextFactory = await InitializeAsync(); + var contextFactory = await InitializeNonSharedTest(); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); _ = await context.WorkUnits .GroupBy(w => 1) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs index a1831786ee1..05f3482a874 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocNavigationsQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocNavigationsQuerySqlServerTest(NonSharedFixture fixture) : AdHocNavigationsQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; #region 10447 @@ -15,8 +15,8 @@ protected override ITestStoreFactory TestStoreFactory [ConditionalFact] public virtual async Task Nested_include_queries_do_not_populate_navigation_twice() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Blogs.Include(b => b.Posts); foreach (var blog in query) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs index b10cefada79..42e560596e9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocPrecompiledQuerySqlServerTest.cs @@ -105,15 +105,15 @@ FROM [Books] AS [b] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType()); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers => SqlServerPrecompiledQueryTestHelpers.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) { - builder = base.AddOptions(builder); + builder = base.AddNonSharedOptions(builder); // TODO: Figure out if there's a nice way to continue using the retrying strategy var sqlServerOptionsBuilder = new SqlServerDbContextOptionsBuilder(builder); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQueryFiltersQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQueryFiltersQuerySqlServerTest.cs index d2e44796c43..a3f7272e3fb 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQueryFiltersQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQueryFiltersQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocQueryFiltersQuerySqlServerTest(NonSharedFixture fixture) : AdHocQueryFiltersQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; #region 8576 @@ -103,8 +103,8 @@ FROM [Entities] AS [e] [ConditionalFact] public virtual async Task Query_filter_with_db_set_should_not_block_other_filters() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Factions.ToList(); Assert.Empty(query); @@ -123,8 +123,8 @@ FROM [Leaders] AS [l] [ConditionalFact] public virtual async Task Keyless_type_used_inside_defining_query() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.LeadersQuery.ToList(); Assert.Single(query); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQuerySplittingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQuerySplittingQuerySqlServerTest.cs index b5d55008a8a..b1f760511a1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQuerySplittingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocQuerySplittingQuerySqlServerTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocQuerySplittingQuerySqlServerTest(NonSharedFixture fixture) : AdHocQuerySplittingQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; private static readonly FieldInfo _querySplittingBehaviorFieldInfo = @@ -43,7 +43,7 @@ protected override DbContextOptionsBuilder ClearQuerySplittingBehavior(DbContext protected override TestStore CreateTestStore25225() { - var testStore = SqlServerTestStore.Create(StoreName, multipleActiveResultSets: true); + var testStore = SqlServerTestStore.Create(NonSharedStoreName, multipleActiveResultSets: true); testStore.UseConnectionString = true; return testStore; } @@ -273,11 +273,11 @@ ORDER BY [p1].[Id] [ConditionalFact] public virtual async Task Using_AsSplitQuery_without_multiple_active_result_sets_works() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( seed: c => c.SeedAsync(), - createTestStore: () => SqlServerTestStore.Create(StoreName, multipleActiveResultSets: false)); + createTestStore: () => SqlServerTestStore.Create(NonSharedStoreName, multipleActiveResultSets: false)); - using var context = contextFactory.CreateContext(); + using var context = contextFactory.CreateDbContext(); context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSplitQuery().ToList(); AssertSql( diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs index 146fb522223..956893060ad 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class EntitySplittingQuerySqlServerTest(NonSharedFixture fixture) : EntitySplittingQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; [ConditionalFact] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsProceduralSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsProceduralSqlServerTest.cs index 29c023e330f..a3e96cbe69b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsProceduralSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsProceduralSqlServerTest.cs @@ -39,7 +39,7 @@ public OperatorsProceduralSqlServerTest(NonSharedFixture fixture, ITestOutputHel ExpectedQueryRewriter = new SqlServerExpectedQueryRewritingVisitor(); } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected override bool DivideByZeroException(Exception ex) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsQuerySqlServerTest.cs index d735817b4b1..cda003b5ba6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OperatorsQuerySqlServerTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OperatorsQuerySqlServerTest(NonSharedFixture fixture) : OperatorsQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected void AssertSql(params string[] expected) @@ -156,8 +156,8 @@ FROM [Owner] AS [o] [ConditionalTheory, MemberData(nameof(IsAsyncData)), SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public virtual async Task Where_AtTimeZone_datetimeoffset_constant(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e in ExpectedData.OperatorEntitiesDateTimeOffset where e.Value.UtcDateTime == new DateTimeOffset(2000, 1, 1, 18, 0, 0, TimeSpan.Zero) @@ -184,8 +184,8 @@ FROM [OperatorEntityDateTimeOffset] AS [o] [ConditionalTheory, MemberData(nameof(IsAsyncData)), SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public virtual async Task Where_AtTimeZone_datetimeoffset_parameter(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var dateTime = new DateTimeOffset(2000, 1, 1, 18, 0, 0, TimeSpan.Zero); var timeZone = "UTC"; @@ -218,8 +218,8 @@ FROM [OperatorEntityDateTimeOffset] AS [o] [ConditionalTheory, MemberData(nameof(IsAsyncData)), SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public virtual async Task Where_AtTimeZone_datetimeoffset_column(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e1 in ExpectedData.OperatorEntitiesDateTimeOffset from e2 in ExpectedData.OperatorEntitiesDateTimeOffset @@ -250,8 +250,8 @@ CROSS JOIN [OperatorEntityDateTimeOffset] AS [o0] [ConditionalTheory, MemberData(nameof(IsAsyncData)), SqlServerCondition(SqlServerCondition.SupportsSqlClr)] public virtual async Task Where_AtTimeZone_is_null(bool async) { - var contextFactory = await InitializeAsync(seed: Seed); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: Seed); + using var context = contextFactory.CreateDbContext(); var expected = (from e in ExpectedData.OperatorEntitiesNullableDateTimeOffset where e.Value == null diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs index 46955dd7e06..e91ee641e95 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs @@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OwnedEntityQuerySqlServerTest(NonSharedFixture fixture) : OwnedEntityQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; #region 22054 @@ -19,8 +19,8 @@ protected override ITestStoreFactory TestStoreFactory [ConditionalFact] public virtual async Task Optional_dependent_is_null_when_sharing_required_column_with_principal() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var query = context.Set().OrderByDescending(e => e.Id).ToList(); Assert.Equal(3, query.Count); Assert.Null(query[0].Contact); @@ -142,8 +142,8 @@ public class Address22054 [ConditionalFact] public virtual async Task Owned_entity_mapped_to_separate_table() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using var context = contextFactory.CreateContext(); + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using var context = contextFactory.CreateDbContext(); var masterTrunk = context.MasterTrunk.OrderBy(e => EF.Property(e, "Id")).FirstOrDefault(); Assert.NotNull(masterTrunk); @@ -238,8 +238,8 @@ public class Currency22340 [ConditionalFact] public virtual async Task Collection_include_on_owner_with_owned_type_mapped_to_different_table() { - var contextFactory = await InitializeAsync(seed: c => c.SeedAsync()); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(seed: c => c.SeedAsync()); + using (var context = contextFactory.CreateDbContext()) { var owner = context.Set().Include(e => e.Dependents).AsSplitQuery().OrderBy(e => e.Id).Single(); Assert.NotNull(owner.Dependents); @@ -272,7 +272,7 @@ FROM [Owner23211] AS [o] """); } - using (var context = contextFactory.CreateContext()) + using (var context = contextFactory.CreateDbContext()) { ClearLog(); var owner = context.Set().Include(e => e.Dependents).AsSplitQuery().OrderBy(e => e.Id) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SharedTypeQuerySqlServerTest.cs index 03ec9da21a7..ac8c02a975b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SharedTypeQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class SharedTypeQuerySqlServerTest(NonSharedFixture fixture) : SharedTypeQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; public override async Task Can_use_shared_type_entity_type_in_query_filter(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalTableSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalTableSqlServerTest.cs index 0c44ef41b8f..e42c1afb295 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalTableSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalTableSqlServerTest.cs @@ -11,13 +11,13 @@ namespace Microsoft.EntityFrameworkCore.Query; [SqlServerCondition(SqlServerCondition.SupportsTemporalTablesCascadeDelete)] public class TemporalTableSqlServerTest(NonSharedFixture fixture) : NonSharedModelTestBase(fixture), IClassFixture { - protected override string StoreName + protected override string NonSharedStoreName => "TemporalTableSqlServerTest"; protected TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; protected void AssertSql(params string[] expected) @@ -26,8 +26,8 @@ protected void AssertSql(params string[] expected) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_basic(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -46,8 +46,8 @@ public virtual async Task Temporal_owned_basic(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_join(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -71,8 +71,8 @@ public virtual async Task Temporal_owned_join(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_set_operation(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -100,8 +100,8 @@ public virtual async Task Temporal_owned_set_operation(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_FromSql(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -130,8 +130,8 @@ public virtual async Task Temporal_owned_FromSql(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_subquery(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -161,8 +161,8 @@ ORDER BY [m0].[Id] DESC [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_complex(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -199,8 +199,8 @@ ORDER BY [s0].[Id] DESC [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_complex_with_nontrivial_alias(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); @@ -237,8 +237,8 @@ ORDER BY [s0].[Id] DESC [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_range_operation_negative(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var message = async ? (await Assert.ThrowsAsync(() @@ -254,8 +254,8 @@ public virtual async Task Temporal_owned_range_operation_negative(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_mapped_to_same_table(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); var query = context.MainEntitiesSameTable.TemporalAsOf(date); @@ -273,8 +273,8 @@ public virtual async Task Temporal_owned_mapped_to_same_table(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_many(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); var query = context.MainEntitiesMany.TemporalAsOf(date); @@ -294,8 +294,8 @@ public virtual async Task Temporal_owned_many(bool async) [ConditionalTheory, MemberData(nameof(IsAsyncData))] public virtual async Task Temporal_owned_with_union(bool async) { - var contextFactory = await InitializeAsync(); - using (var context = contextFactory.CreateContext()) + var contextFactory = await InitializeNonSharedTest(); + using (var context = contextFactory.CreateDbContext()) { var date = new DateTime(2000, 1, 1); var query = context.MainEntitiesMany.TemporalAsOf(date) @@ -437,7 +437,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public virtual async Task Temporal_can_query_shared_derived_hierarchy(bool async) { var contectFactory = await InitializeAsync(OnModelCreating); - using var context = contectFactory.CreateContext(); + using var context = contectFactory.CreateDbContext(); var query = context.Set().TemporalAsOf(new DateTime(2000, 1, 1)); var _ = async ? await query.ToListAsync() : query.ToList(); @@ -452,7 +452,7 @@ WHERE [v].[Capacity] IS NOT NULL AND [v].[FuelTank_Discriminator] IS NOT NULL protected Task> InitializeAsync( Action onModelCreating, bool seed = true) - => InitializeAsync( + => InitializeNonSharedTest( onModelCreating, shouldLogCategory: _ => true, seed: seed ? c => c.SeedAsync() : null); protected virtual void OnModelCreating(ModelBuilder modelBuilder) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ToSqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ToSqlQuerySqlServerTest.cs index 929daea63e6..2b7054dceac 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ToSqlQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ToSqlQuerySqlServerTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class ToSqlQuerySqlServerTest(NonSharedFixture fixture) : ToSqlQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; [ConditionalFact] diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs index 9e10fbd86c5..227e09d30c9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/CompiledModelSqlServerTest.cs @@ -482,12 +482,12 @@ public virtual Task SpatialTypesTest() protected override TestHelpers TestHelpers => SqlServerTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) { - builder = base.AddOptions(builder) + builder = base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w.Ignore(SqlServerEventId.DecimalTypeDefaultWarning)); new SqlServerDbContextOptionsBuilder(builder).UseNetTopologySuite(); return builder; diff --git a/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs index 1fd5174360d..504ef5454c7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; public class TPTTableSplittingSqlServerTest(NonSharedFixture fixture, ITestOutputHelper testOutputHelper) : TPTTableSplittingTestBase(fixture, testOutputHelper) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; public override async Task Can_use_with_redundant_relationships() diff --git a/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs index 2f599c96413..e118d9ba864 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore; public class TableSplittingSqlServerTest(NonSharedFixture fixture, ITestOutputHelper testOutputHelper) : TableSplittingTestBase(fixture, testOutputHelper) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; public override async Task Can_use_with_redundant_relationships() diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/NonSharedModelUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/NonSharedModelUpdatesSqlServerTest.cs index 683bbd3e7ed..c222d2a1386 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/NonSharedModelUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/NonSharedModelUpdatesSqlServerTest.cs @@ -89,7 +89,7 @@ OUTPUT 1 [ConditionalFact] // Issue #29502 public virtual async Task Bulk_insert_result_set_mapping() { - var contextFactory = await InitializeAsync( + var contextFactory = await InitializeNonSharedTest( onModelCreating: mb => { mb.Entity().ToTable("Users"); @@ -137,7 +137,7 @@ public override async Task DbUpdateException_Entries_is_correct_with_multiple_in // SQL Server's bulk insert support makes it impossible to populate the entry which caused the exception, since the position // used to find the entry is returned as an output column, but the row is never received in case of an exception. // Instead we make sure Entries contains all entries. - var contextFactory = await InitializeAsync(onModelCreating: mb => mb.Entity().HasIndex(b => b.Name).IsUnique()); + var contextFactory = await InitializeNonSharedTest(onModelCreating: mb => mb.Entity().HasIndex(b => b.Name).IsUnique()); await ExecuteWithStrategyInTransactionAsync( contextFactory, @@ -195,6 +195,6 @@ WHEN NOT MATCHED THEN private void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; } diff --git a/test/EFCore.SqlServer.FunctionalTests/Update/StoredProcedureUpdateSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Update/StoredProcedureUpdateSqlServerTest.cs index 413b86e73ad..c91ff93686f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Update/StoredProcedureUpdateSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Update/StoredProcedureUpdateSqlServerTest.cs @@ -700,6 +700,6 @@ OUTPUT 1 protected override void ConfigureStoreGeneratedConcurrencyToken(EntityTypeBuilder entityTypeBuilder, string propertyName) => entityTypeBuilder.Property(propertyName).IsRowVersion(); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqlServerTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs index a41ee6f5bc7..a14ae68b938 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.BulkUpdates; public class NonSharedModelBulkUpdatesSqliteTest(NonSharedFixture fixture) : NonSharedModelBulkUpdatesRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; [ConditionalFact] @@ -247,8 +247,8 @@ public override async Task Update_complex_type_property_with_view_mapping(bool a """); } - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(wcb => wcb.Log(SqliteEventId.CompositeKeyWithValueGeneration)); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder).ConfigureWarnings(wcb => wcb.Log(SqliteEventId.CompositeKeyWithValueGeneration)); private void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); diff --git a/test/EFCore.Sqlite.FunctionalTests/EntitySplittingSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/EntitySplittingSqliteTest.cs index 418c072fb47..3c2befe026d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/EntitySplittingSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/EntitySplittingSqliteTest.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore; public class EntitySplittingSqliteTest(NonSharedFixture fixture, ITestOutputHelper testOutputHelper) : EntitySplittingTestBase(fixture, testOutputHelper) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs index 08a6e784d2b..275ec4bb056 100644 --- a/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/JsonTypesSqliteTest.cs @@ -219,12 +219,12 @@ public override Task Can_read_write_collection_of_nullable_ulong_enum_JSON_value """{"Prop":[0,null,18446744073709551615,0,1,8]}""", mappedCollection: true); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) { - builder = base.AddOptions(builder) + builder = base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w .Ignore(SqliteEventId.SchemaConfiguredWarning) .Ignore(SqliteEventId.CompositeKeyWithValueGeneration)); diff --git a/test/EFCore.Sqlite.FunctionalTests/MaterializationInterceptionSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/MaterializationInterceptionSqliteTest.cs index 16aafe82d57..71802f6de15 100644 --- a/test/EFCore.Sqlite.FunctionalTests/MaterializationInterceptionSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/MaterializationInterceptionSqliteTest.cs @@ -27,6 +27,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) #pragma warning restore EF8001 } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqliteTest.cs index 71a98a4e5cc..702194f2d90 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocAdvancedMappingsQuerySqliteTest.cs @@ -7,6 +7,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocAdvancedMappingsQuerySqliteTest(NonSharedFixture fixture) : AdHocAdvancedMappingsQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs index 95b458d6668..08a4d239cd5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs @@ -5,6 +5,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocComplexTypeQuerySqliteTest(NonSharedFixture fixture) : AdHocComplexTypeQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs index 5aa4bb84dd1..0cff495dc96 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocJsonQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocJsonQuerySqliteTest(NonSharedFixture fixture) : AdHocJsonQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; protected override async Task Seed21006(Context21006 context) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocManyToManyQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocManyToManyQuerySqliteTest.cs index 630292d817e..523f4800be6 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocManyToManyQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocManyToManyQuerySqliteTest.cs @@ -7,6 +7,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocManyToManyQuerySqliteTest(NonSharedFixture fixture) : AdHocManyToManyQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs index 4438f8089c8..9a71b1de649 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocMiscellaneousQuerySqliteTest(NonSharedFixture fixture) : AdHocMiscellaneousQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; protected override DbContextOptionsBuilder SetParameterizedCollectionMode( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocNavigationsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocNavigationsQuerySqliteTest.cs index f19141e389d..1dd28e7d943 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocNavigationsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocNavigationsQuerySqliteTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocNavigationsQuerySqliteTest(NonSharedFixture fixture) : AdHocNavigationsQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; public override async Task Projection_with_multiple_includes_and_subquery_with_set_operation() diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocPrecompiledQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocPrecompiledQuerySqliteTest.cs index 46d4a96625c..90ca92501a0 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocPrecompiledQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocPrecompiledQuerySqliteTest.cs @@ -9,7 +9,7 @@ public class AdHocPrecompiledQuerySqliteTest(NonSharedFixture fixture, ITestOutp protected override bool AlwaysPrintGeneratedSources => false; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; protected override PrecompiledQueryTestHelpers PrecompiledQueryTestHelpers diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQueryFiltersQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQueryFiltersQuerySqliteTest.cs index 9916840f733..830ff841272 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQueryFiltersQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQueryFiltersQuerySqliteTest.cs @@ -7,6 +7,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocQueryFiltersQuerySqliteTest(NonSharedFixture fixture) : AdHocQueryFiltersQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs index 904282336db..8341a09f6b5 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocQuerySplittingQuerySqliteTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class AdHocQuerySplittingQuerySqliteTest(NonSharedFixture fixture) : AdHocQuerySplittingQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; private static readonly FieldInfo _querySplittingBehaviorFieldInfo = diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs index 40fa28d41c7..c874637415f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class EntitySplittingQuerySqliteTest(NonSharedFixture fixture) : EntitySplittingQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; public override async Task Normal_entity_owning_a_split_reference_with_main_fragment_not_sharing(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsProceduralSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsProceduralSqliteTest.cs index 1bbbb354b43..b76b1ecedd7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsProceduralSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsProceduralSqliteTest.cs @@ -7,6 +7,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OperatorsProceduralSqliteTest(NonSharedFixture fixture) : OperatorsProceduralQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsQuerySqliteTest.cs index 9b7d7e3957f..28110c46c7c 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/OperatorsQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OperatorsQuerySqliteTest(NonSharedFixture fixture) : OperatorsQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; protected void AssertSql(params string[] expected) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/OwnedEntityQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/OwnedEntityQuerySqliteTest.cs index d9f43403d3d..d006eaaa8bc 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/OwnedEntityQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/OwnedEntityQuerySqliteTest.cs @@ -7,9 +7,9 @@ namespace Microsoft.EntityFrameworkCore.Query; public class OwnedEntityQuerySqliteTest(NonSharedFixture fixture) : OwnedEntityQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder.ConfigureWarnings(b => b.Ignore(SqliteEventId.CompositeKeyWithValueGeneration))); + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) + => base.AddNonSharedOptions(builder.ConfigureWarnings(b => b.Ignore(SqliteEventId.CompositeKeyWithValueGeneration))); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 2701a648b2e..cb03a131aa8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -1442,6 +1442,33 @@ LIMIT 2 """); } + public override async Task Parameter_with_inferred_value_converter() + { + await base.Parameter_with_inferred_value_converter(); + + AssertSql(""); + } + + public override async Task Constant_with_inferred_value_converter() + { + await base.Constant_with_inferred_value_converter(); + + AssertSql( + """ +SELECT "t"."Id", "t"."Ints", "t"."PropertyWithValueConverter" +FROM "TestEntity" AS "t" +WHERE ( + SELECT COUNT(*) + FROM (SELECT CAST(1 AS INTEGER) AS "Value" UNION ALL VALUES (8)) AS "v" + WHERE "v"."Value" = "t"."PropertyWithValueConverter") = 1 +LIMIT 2 +"""); + } + + [ConditionalFact] + public override Task Multidimensional_array_is_not_supported() + => base.Multidimensional_array_is_not_supported(); + public override async Task Contains_on_Enumerable() { await base.Contains_on_Enumerable(); @@ -2512,6 +2539,29 @@ END IN (@strings1, @strings2, @strings3) """); } + public override async Task Project_collection_from_entity_type_with_owned() + { + await base.Project_collection_from_entity_type_with_owned(); + + AssertSql( + """ +SELECT "t"."Ints" +FROM "TestEntityWithOwned" AS "t" +"""); + } + + public override async Task Subquery_over_primitive_collection_on_inheritance_derived_type() + { + await base.Subquery_over_primitive_collection_on_inheritance_derived_type(); + + AssertSql( + """ +SELECT "b"."Id", "b"."Discriminator", "b"."Ints" +FROM "BaseType" AS "b" +WHERE json_array_length("b"."Ints") > 0 +"""); + } + [ConditionalFact] public async Task Empty_string_used_for_primitive_collection_throws() { diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/SharedTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/SharedTypeQuerySqliteTest.cs index dda374a5b82..0dd9be49233 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/SharedTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/SharedTypeQuerySqliteTest.cs @@ -7,6 +7,6 @@ namespace Microsoft.EntityFrameworkCore.Query; public class SharedTypeQuerySqliteTest(NonSharedFixture fixture) : SharedTypeQueryRelationalTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ToSqlQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ToSqlQuerySqliteTest.cs index 2a2c6730b71..b8b09e85e5b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ToSqlQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ToSqlQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class ToSqlQuerySqliteTest(NonSharedFixture fixture) : ToSqlQueryTestBase(fixture) { - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; [ConditionalFact] diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs index 5b405ec9197..7064032baab 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs @@ -109,12 +109,12 @@ public override Task Tpc_Sprocs() protected override TestHelpers TestHelpers => SqliteTestHelpers.Instance; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; - protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) + protected override DbContextOptionsBuilder AddNonSharedOptions(DbContextOptionsBuilder builder) { - builder = base.AddOptions(builder) + builder = base.AddNonSharedOptions(builder) .ConfigureWarnings(w => w .Ignore(SqliteEventId.SchemaConfiguredWarning) .Ignore(SqliteEventId.CompositeKeyWithValueGeneration)); diff --git a/test/EFCore.Sqlite.FunctionalTests/TPTTableSplittingSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/TPTTableSplittingSqliteTest.cs index 9bc08c83cbe..1b818757ded 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TPTTableSplittingSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TPTTableSplittingSqliteTest.cs @@ -12,6 +12,6 @@ public override Task Can_insert_dependent_with_just_one_parent() // This scenario is not valid for TPT => Task.CompletedTask; - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/TableSplittingSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/TableSplittingSqliteTest.cs index 4d78b09a94e..8fc1ae5b6f7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TableSplittingSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TableSplittingSqliteTest.cs @@ -38,6 +38,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .Property(e => e.Computed).HasComputedColumnSql("1"); } - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Update/NonSharedModelUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Update/NonSharedModelUpdatesSqliteTest.cs index bcbead6b6bb..c81f36eefd7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Update/NonSharedModelUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Update/NonSharedModelUpdatesSqliteTest.cs @@ -113,6 +113,6 @@ public override async Task DbUpdateException_Entries_is_correct_with_multiple_in private void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); - protected override ITestStoreFactory TestStoreFactory + protected override ITestStoreFactory NonSharedTestStoreFactory => SqliteTestStoreFactory.Instance; }