From 7e7589563ac9bf3a370a801ac86ce03b8dbc8a89 Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Thu, 28 Oct 2021 15:37:04 -0700 Subject: [PATCH] Query: Identify Contains on IReadOnlySet/IImmutableSet Resolves #26437 --- src/Shared/MethodInfoExtensions.cs | 7 +++++- ...thwindAggregateOperatorsQueryCosmosTest.cs | 20 ++++++++++++++++ ...orthwindAggregateOperatorsQueryTestBase.cs | 24 +++++++++++++++++++ ...indAggregateOperatorsQuerySqlServerTest.cs | 20 ++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/Shared/MethodInfoExtensions.cs b/src/Shared/MethodInfoExtensions.cs index 0a784b90bf2..abdcd5b2dc0 100644 --- a/src/Shared/MethodInfoExtensions.cs +++ b/src/Shared/MethodInfoExtensions.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; #nullable enable @@ -16,6 +17,10 @@ public static bool IsContainsMethod(this MethodInfo method) && method.DeclaringType != null && method.DeclaringType.GetInterfaces().Append(method.DeclaringType).Any( t => t == typeof(IList) - || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>))); + || (t.IsGenericType + && t.GetGenericTypeDefinition() is Type genericType + && (genericType == typeof(ICollection<>) + || genericType == typeof(IReadOnlySet<>) + || genericType == typeof(IImmutableSet<>)))); } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs index 73fdff401a1..16c71eae3d3 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs @@ -1452,6 +1452,26 @@ FROM root c WHERE ((c[""Discriminator""] = ""Order"") AND c[""OrderID""] IN (10248, 10249))"); } + public override async Task IImmutableSet_Contains_with_parameter(bool async) + { + await base.IImmutableSet_Contains_with_parameter(async); + + AssertSql( + @"SELECT c +FROM root c +WHERE ((c[""Discriminator""] = ""Customer"") AND c[""CustomerID""] IN (""ALFKI""))"); + } + + public override async Task IReadOnlySet_Contains_with_parameter(bool async) + { + await base.IReadOnlySet_Contains_with_parameter(async); + + AssertSql( + @"SELECT c +FROM root c +WHERE ((c[""Discriminator""] = ""Customer"") AND c[""CustomerID""] IN (""ALFKI""))"); + } + public override async Task HashSet_Contains_with_parameter(bool async) { await base.HashSet_Contains_with_parameter(async); diff --git a/test/EFCore.Specification.Tests/Query/NorthwindAggregateOperatorsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindAggregateOperatorsQueryTestBase.cs index c47013e598d..dc1be9bc445 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindAggregateOperatorsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindAggregateOperatorsQueryTestBase.cs @@ -1537,6 +1537,30 @@ public virtual Task Contains_with_constant_list_value_type_id(bool async) entryCount: 2); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task IImmutableSet_Contains_with_parameter(bool async) + { + IImmutableSet ids = ImmutableHashSet.Empty.Add("ALFKI"); + + return AssertQuery( + async, + ss => ss.Set().Where(c => ids.Contains(c.CustomerID)), + entryCount: 1); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task IReadOnlySet_Contains_with_parameter(bool async) + { + IReadOnlySet ids = new HashSet { "ALFKI" }; + + return AssertQuery( + async, + ss => ss.Set().Where(c => ids.Contains(c.CustomerID)), + entryCount: 1); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task HashSet_Contains_with_parameter(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs index d2c3abcb23a..1432d62b34c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs @@ -1758,6 +1758,26 @@ FROM [Orders] AS [o] WHERE [o].[OrderID] IN (10248, 10249)"); } + public override async Task IImmutableSet_Contains_with_parameter(bool async) + { + await base.IImmutableSet_Contains_with_parameter(async); + + AssertSql( + @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] +FROM [Customers] AS [c] +WHERE [c].[CustomerID] = N'ALFKI'"); + } + + public override async Task IReadOnlySet_Contains_with_parameter(bool async) + { + await base.IReadOnlySet_Contains_with_parameter(async); + + AssertSql( + @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] +FROM [Customers] AS [c] +WHERE [c].[CustomerID] = N'ALFKI'"); + } + public override async Task HashSet_Contains_with_parameter(bool async) { await base.HashSet_Contains_with_parameter(async);