diff --git a/src/EFCore/Query/ReplacingExpressionVisitor.cs b/src/EFCore/Query/ReplacingExpressionVisitor.cs index ae8033b8b5a..f0f67b5acc2 100644 --- a/src/EFCore/Query/ReplacingExpressionVisitor.cs +++ b/src/EFCore/Query/ReplacingExpressionVisitor.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; @@ -60,7 +61,7 @@ protected override Expression VisitMember(MemberExpression memberExpression) if (innerExpression is MemberInitExpression memberInitExpression && memberInitExpression.Bindings.SingleOrDefault( - mb => mb.Member == memberExpression.Member) is MemberAssignment memberAssignment) + mb => mb.Member.IsSameAs(memberExpression.Member)) is MemberAssignment memberAssignment) { return memberAssignment.Expression; } diff --git a/src/Shared/MemberInfoExtensions.cs b/src/Shared/MemberInfoExtensions.cs index 06b1b2a05a0..380871815dd 100644 --- a/src/Shared/MemberInfoExtensions.cs +++ b/src/Shared/MemberInfoExtensions.cs @@ -31,16 +31,5 @@ public static string GetSimpleMemberName(this MemberInfo member) var index = name.LastIndexOf('.'); return index >= 0 ? name.Substring(index + 1) : name; } - - private sealed class MemberInfoComparer : IEqualityComparer - { - public static readonly MemberInfoComparer Instance = new MemberInfoComparer(); - - public bool Equals(MemberInfo x, MemberInfo y) - => x.IsSameAs(y); - - public int GetHashCode(MemberInfo obj) - => obj.GetHashCode(); - } } } diff --git a/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs b/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs index 7ccf0219e2e..8795e99a559 100644 --- a/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; +using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestModels.Inheritance; @@ -523,8 +524,6 @@ public virtual void Setting_foreign_key_to_a_different_type_throws() } } - protected virtual bool EnforcesFkConstraints => true; - [ConditionalFact] public virtual void Byte_enum_value_constant_used_in_projection() { @@ -536,8 +535,32 @@ public virtual void Byte_enum_value_constant_used_in_projection() Assert.Equal(Island.North, result[0]); } + [ConditionalFact] + public virtual void Member_access_on_intermediate_type_works() + { + using var context = CreateContext(); + var query = context.Set().Select(k => new Kiwi { Name = k.Name }); + + var parameter = Expression.Parameter(query.ElementType, "p"); + var property = Expression.Property(parameter, "Name"); + var getProperty = Expression.Lambda(property, new[] { parameter }); + + var expression = Expression.Call(typeof(Queryable), nameof(Queryable.OrderBy), + new[] { query.ElementType, typeof(string) }, + new[] { query.Expression, Expression.Quote(getProperty) }); + + query = query.Provider.CreateQuery(expression); + + var result = query.ToList(); + + var kiwi = Assert.Single(result); + Assert.Equal("Great spotted kiwi", kiwi.Name); + } + protected InheritanceContext CreateContext() => Fixture.CreateContext(); + protected virtual bool EnforcesFkConstraints => true; + protected virtual void ClearLog() { } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceSqlServerTest.cs index f9d3ca80b02..dd0f818fce9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceSqlServerTest.cs @@ -500,6 +500,17 @@ FROM [Animal] AS [a0] WHERE CAST(0 AS bit) = CAST(1 AS bit)"); } + public override void Member_access_on_intermediate_type_works() + { + base.Member_access_on_intermediate_type_works(); + + AssertSql( + @"SELECT [a].[Name] +FROM [Animal] AS [a] +WHERE [a].[Discriminator] = N'Kiwi' +ORDER BY [a].[Name]"); + } + protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) => facade.UseTransaction(transaction.GetDbTransaction());