Skip to content

Commit

Permalink
Don't throw exception when NotMapped attribute is overriden by explic…
Browse files Browse the repository at this point in the history
…it configuration

Fixes #16630
  • Loading branch information
AndriySvyryd committed Aug 1, 2019
1 parent 14ab20e commit 973cdf4
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 41 deletions.
41 changes: 12 additions & 29 deletions src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,40 +171,19 @@ public virtual Expression BindNavigation(INavigation navigation, bool clientEval
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
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);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// 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.
/// </summary>
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
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Cosmos/Update/Internal/DocumentSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions src/EFCore/Infrastructure/ModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
16 changes: 7 additions & 9 deletions test/EFCore.Specification.Tests/DataAnnotationTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,13 @@ public virtual void NotMapped_on_base_class_property_ignores_it()
var modelBuilder = CreateModelBuilder();

modelBuilder.Entity<Unit1>();
modelBuilder.Entity<BaseEntity1>();
modelBuilder.Entity<BaseEntity1>().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"));
Expand Down Expand Up @@ -342,18 +342,16 @@ public virtual void NotMapped_on_base_class_property_discovered_through_navigati
}

[ConditionalFact]
public virtual void NotMapped_on_overridden_mapped_base_class_property_throws()
public virtual void NotMapped_on_overridden_property_is_ignored()
{
var modelBuilder = CreateModelBuilder();

modelBuilder.Entity<Unit3>();
modelBuilder.Entity<BaseEntity3>();

Assert.Equal(
CoreStrings.InheritedPropertyCannotBeIgnored(
nameof(Unit3.VirtualBaseClassProperty), typeof(Unit3).ShortDisplayName(), typeof(BaseEntity3).ShortDisplayName()),
Assert.Throws<InvalidOperationException>(
() => Validate(modelBuilder)).Message);
Assert.NotNull(modelBuilder.Model.FindEntityType(typeof(Unit3)).FindProperty("VirtualBaseClassProperty"));

Validate(modelBuilder);
}

[ConditionalFact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1722,9 +1722,11 @@ private void VerifyIgnoreMember(
var addedEntityTypeBuilder = modelBuilder.Entity(typeof(SpecialOrderMinimal), ConfigurationSource.Convention);
Assert.False(findMember(addedEntityTypeBuilder));

var exceptionExpected = ignoredOnType == typeof(ExtraSpecialOrderMinimal);
var exceptionExpected = ignoredOnType == typeof(ExtraSpecialOrderMinimal)
&& (ignoreConfigurationSource == ConfigurationSource.Explicit
|| (!ignoredFirst && setBaseFirst));

var expectedAdded = exceptionExpected
var expectedAdded = ignoredOnType == typeof(ExtraSpecialOrderMinimal)
|| (addConfigurationSource.Overrides(ignoreConfigurationSource)
&& (ignoreConfigurationSource != ConfigurationSource.Explicit
|| ignoredOnType != typeof(SpecialOrderMinimal)
Expand Down

0 comments on commit 973cdf4

Please sign in to comment.