From cbb151e6a0dd3fd35dc18e260c10894eefa5a4aa Mon Sep 17 00:00:00 2001 From: AndriySvyryd Date: Wed, 31 Jul 2019 13:39:45 -0700 Subject: [PATCH] Don't throw exception when NotMapped attribute is overriden by explicit configuration Fixes #16630 --- .../Internal/EntityProjectionExpression.cs | 41 ++++++------------- .../Update/Internal/DocumentSource.cs | 2 +- src/EFCore/Infrastructure/ModelValidator.cs | 5 +++ .../DataAnnotationTestBase.cs | 6 +-- 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs index 0162424df4a..50384104263 100644 --- a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs @@ -171,32 +171,7 @@ public virtual Expression BindNavigation(INavigation navigation, bool clientEval /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Expression BindMember(string name, Type entityClrType, bool clientEval, out IPropertyBase propertyBase) - { - var entityType = EntityType; - if (entityClrType != null - && !entityClrType.IsAssignableFrom(entityType.ClrType)) - { - entityType = entityType.GetDerivedTypes().First(e => entityClrType.IsAssignableFrom(e.ClrType)); - } - - var property = entityType.FindProperty(name); - if (property != null) - { - propertyBase = property; - return BindProperty(property, clientEval); - } - - var navigation = entityType.FindNavigation(name); - if (navigation != null) - { - propertyBase = navigation; - return BindNavigation(navigation, clientEval); - } - - // Entity member not found - propertyBase = null; - return null; - } + => BindMember(MemberIdentity.Create(name), entityClrType, clientEval, out propertyBase); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -204,7 +179,11 @@ public virtual Expression BindMember(string name, Type entityClrType, bool clien /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual Expression BindMember(MemberInfo memberInfo, Type entityClrType, bool clientEval, out IPropertyBase propertyBase) + public virtual Expression BindMember( + MemberInfo memberInfo, Type entityClrType, bool clientEval, out IPropertyBase propertyBase) + => BindMember(MemberIdentity.Create(memberInfo), entityClrType, clientEval, out propertyBase); + + private Expression BindMember(MemberIdentity member, Type entityClrType, bool clientEval, out IPropertyBase propertyBase) { var entityType = EntityType; if (entityClrType != null @@ -213,14 +192,18 @@ public virtual Expression BindMember(MemberInfo memberInfo, Type entityClrType, entityType = entityType.GetDerivedTypes().First(e => entityClrType.IsAssignableFrom(e.ClrType)); } - var property = entityType.FindProperty(memberInfo); + var property = member.MemberInfo == null + ? entityType.FindProperty(member.Name) + : entityType.FindProperty(member.MemberInfo); if (property != null) { propertyBase = property; return BindProperty(property, clientEval); } - var navigation = entityType.FindNavigation(memberInfo); + var navigation = member.MemberInfo == null + ? entityType.FindNavigation(member.Name) + : entityType.FindNavigation(member.MemberInfo); if (navigation != null) { propertyBase = navigation; diff --git a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs index 55eb47bea39..8d49ae081e5 100644 --- a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs +++ b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs @@ -169,7 +169,7 @@ public virtual JObject UpdateDocument(JObject document, IUpdateEntry entry) var embeddedEntry = ((InternalEntityEntry)entry).StateManager.TryGetEntry(embeddedValue, fk.DeclaringEntityType); if (embeddedEntry == null) { - return document; + continue; } var embeddedDocument = embeddedDocumentSource.GetCurrentDocument(embeddedEntry); diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs index 2d505bc1e58..2f2f8a64e48 100644 --- a/src/EFCore/Infrastructure/ModelValidator.cs +++ b/src/EFCore/Infrastructure/ModelValidator.cs @@ -250,6 +250,11 @@ protected virtual void ValidateIgnoredMembers([NotNull] IModel model, [NotNull] { foreach (var ignoredMember in entityType.GetIgnoredMembers()) { + if (entityType.FindIgnoredConfigurationSource(ignoredMember) != ConfigurationSource.Explicit) + { + continue; + } + var property = entityType.FindProperty(ignoredMember); if (property != null) { diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index 84c7080dd59..170c00ecfcb 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -243,13 +243,13 @@ public virtual void NotMapped_on_base_class_property_ignores_it() var modelBuilder = CreateModelBuilder(); modelBuilder.Entity(); - modelBuilder.Entity(); + modelBuilder.Entity().Property(e => e.BaseClassProperty); Validate(modelBuilder); Assert.Null(modelBuilder.Model.FindEntityType(typeof(AbstractBaseEntity1)).FindProperty("BaseClassProperty")); - Assert.Null(modelBuilder.Model.FindEntityType(typeof(BaseEntity1)).FindProperty("BaseClassProperty")); - Assert.Null(modelBuilder.Model.FindEntityType(typeof(Unit1)).FindProperty("BaseClassProperty")); + Assert.NotNull(modelBuilder.Model.FindEntityType(typeof(BaseEntity1)).FindProperty("BaseClassProperty")); + Assert.NotNull(modelBuilder.Model.FindEntityType(typeof(Unit1)).FindProperty("BaseClassProperty")); Assert.Null(modelBuilder.Model.FindEntityType(typeof(AbstractBaseEntity1)).FindProperty("VirtualBaseClassProperty")); Assert.Null(modelBuilder.Model.FindEntityType(typeof(BaseEntity1)).FindProperty("VirtualBaseClassProperty")); Assert.Null(modelBuilder.Model.FindEntityType(typeof(Unit1)).FindProperty("VirtualBaseClassProperty"));