Skip to content

Commit

Permalink
Don't clear discriminator values when discovering a new non-root base…
Browse files Browse the repository at this point in the history
… type.

Fixes #18385
  • Loading branch information
AndriySvyryd committed Oct 24, 2019
1 parent b52d5fc commit 652e791
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/EFCore/Metadata/Internal/EntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2451,8 +2451,8 @@ public virtual void SetDiscriminatorProperty([CanBeNull] IProperty property, Con
{
CheckDiscriminatorProperty(property);

if ((property == null
|| !property.ClrType.IsInstanceOfType(this.GetDiscriminatorValue())))
if (((property == null && BaseType == null)
|| (property != null && !property.ClrType.IsInstanceOfType(this.GetDiscriminatorValue()))))
{
((IMutableEntityType)this).RemoveDiscriminatorValue();
if (BaseType == null)
Expand Down
41 changes: 31 additions & 10 deletions test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
Expand Down Expand Up @@ -44,9 +45,8 @@ public virtual void Can_map_derived_types_first()

modelBuilder.Entity<SpecialBookLabel>().Property(b => b.BookId);

modelBuilder.FinalizeModel();
var model = modelBuilder.FinalizeModel();

var model = modelBuilder.Model;
Assert.Empty(model.FindEntityType(typeof(ExtraSpecialBookLabel)).GetDeclaredProperties());
Assert.Empty(model.FindEntityType(typeof(SpecialBookLabel)).GetDeclaredProperties());
Assert.NotNull(model.FindEntityType(typeof(SpecialBookLabel)).FindProperty(nameof(BookLabel.BookId)));
Expand All @@ -62,9 +62,8 @@ public virtual void Base_types_are_mapped_correctly_if_discovered_last()
modelBuilder.Entity<ExtraSpecialBookLabel>();
modelBuilder.Entity<SpecialBookLabel>().Ignore(b => b.BookLabel);

modelBuilder.FinalizeModel();
var model = modelBuilder.FinalizeModel();

var model = modelBuilder.Model;
var moreDerived = model.FindEntityType(typeof(ExtraSpecialBookLabel));
var derived = model.FindEntityType(typeof(SpecialBookLabel));
var baseType = model.FindEntityType(typeof(BookLabel));
Expand All @@ -73,6 +72,28 @@ public virtual void Base_types_are_mapped_correctly_if_discovered_last()
Assert.Same(derived, moreDerived.BaseType);
}

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

modelBuilder.Ignore<P>();

modelBuilder.Entity<PBase>()
.HasDiscriminator<int>("TypeDiscriminator")
.HasValue<T>(1)
.HasValue<Q>(2);

modelBuilder.Entity<P>();

var model = modelBuilder.FinalizeModel();

Assert.Null(model.FindEntityType(typeof(PBase)).GetDiscriminatorValue());
Assert.Null(model.FindEntityType(typeof(P)).GetDiscriminatorValue());
Assert.Equal(1, model.FindEntityType(typeof(T)).GetDiscriminatorValue());
Assert.Equal(2, model.FindEntityType(typeof(Q)).GetDiscriminatorValue());
}

[ConditionalFact]
public virtual void Can_map_derived_self_ref_many_to_one()
{
Expand Down Expand Up @@ -828,34 +849,34 @@ public void Base_type_can_be_discovered_after_creating_foreign_keys_on_derived()
Assert.Equal(ValueGenerated.OnAdd, mb.Model.FindEntityType(typeof(Q)).FindProperty(nameof(Q.ID)).ValueGenerated);
}

public class L
protected class L
{
public int Id { get; set; }
public IList<T> Ts { get; set; }
}

public class T : P
protected class T : P
{
public Q D { get; set; }
public P P { get; set; }
public Q F { get; set; }
}

public class P : PBase
protected abstract class P : PBase
{
}

public class Q : PBase
protected class Q : PBase
{
}

public abstract class PBase
protected abstract class PBase
{
public int ID { get; set; }
public string Stuff { get; set; }
}

public class AL
protected class AL
{
public int Id { get; set; }
public PBase L { get; set; }
Expand Down
35 changes: 35 additions & 0 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,44 @@ public override DataBuilder<TEntity> HasData(IEnumerable<TEntity> data)
public override DataBuilder<TEntity> HasData(IEnumerable<object> data)
=> EntityTypeBuilder.HasData(data);

public override TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(
Expression<Func<TEntity, TDiscriminator>> propertyExpression)
=> new GenericTestDiscriminatorBuilder<TDiscriminator>(EntityTypeBuilder.HasDiscriminator(propertyExpression));

public override TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(string propertyName)
=> new GenericTestDiscriminatorBuilder<TDiscriminator>(EntityTypeBuilder.HasDiscriminator<TDiscriminator>(propertyName));

public override TestEntityTypeBuilder<TEntity> HasNoDiscriminator()
=> Wrap(EntityTypeBuilder.HasNoDiscriminator());

public EntityTypeBuilder<TEntity> Instance => EntityTypeBuilder;
}

protected class GenericTestDiscriminatorBuilder<TDiscriminator> : TestDiscriminatorBuilder<TDiscriminator>
{
public GenericTestDiscriminatorBuilder(DiscriminatorBuilder<TDiscriminator> discriminatorBuilder)
{
DiscriminatorBuilder = discriminatorBuilder;
}

protected DiscriminatorBuilder<TDiscriminator> DiscriminatorBuilder { get; }

protected virtual TestDiscriminatorBuilder<TDiscriminator> Wrap(DiscriminatorBuilder<TDiscriminator> discriminatorBuilder)
=> new GenericTestDiscriminatorBuilder<TDiscriminator>(discriminatorBuilder);

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue<TEntity>(TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue<TEntity>(value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(Type entityType, TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(entityType, value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(string entityTypeName, TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(entityTypeName, value));
}

protected class GenericTestOwnedEntityTypeBuilder<TEntity> : TestOwnedEntityTypeBuilder<TEntity>,
IInfrastructure<OwnedEntityTypeBuilder<TEntity>>
where TEntity : class
Expand Down
37 changes: 37 additions & 0 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,46 @@ public override DataBuilder<TEntity> HasData(IEnumerable<object> data)
return new DataBuilder<TEntity>();
}

public override TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(
Expression<Func<TEntity, TDiscriminator>> propertyExpression)
=> new NonGenericTestDiscriminatorBuilder<TDiscriminator>(
EntityTypeBuilder.HasDiscriminator(propertyExpression?.GetPropertyAccess().GetSimpleMemberName(), typeof(TDiscriminator)));

public override TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(string propertyName)
=> new NonGenericTestDiscriminatorBuilder<TDiscriminator>(
EntityTypeBuilder.HasDiscriminator(propertyName, typeof(TDiscriminator)));

public override TestEntityTypeBuilder<TEntity> HasNoDiscriminator()
=> Wrap(EntityTypeBuilder.HasNoDiscriminator());

public EntityTypeBuilder Instance => EntityTypeBuilder;
}

protected class NonGenericTestDiscriminatorBuilder<TDiscriminator> : TestDiscriminatorBuilder<TDiscriminator>
{
public NonGenericTestDiscriminatorBuilder(DiscriminatorBuilder discriminatorBuilder)
{
DiscriminatorBuilder = discriminatorBuilder;
}

protected DiscriminatorBuilder DiscriminatorBuilder { get; }

protected virtual TestDiscriminatorBuilder<TDiscriminator> Wrap(DiscriminatorBuilder discriminatorBuilder)
=> new NonGenericTestDiscriminatorBuilder<TDiscriminator>(discriminatorBuilder);

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue<TEntity>(TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue<TEntity>(value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(Type entityType, TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(entityType, value));

public override TestDiscriminatorBuilder<TDiscriminator> HasValue(string entityTypeName, TDiscriminator value)
=> Wrap(DiscriminatorBuilder.HasValue(entityTypeName, value));
}

protected class NonGenericTestOwnedEntityTypeBuilder<TEntity> : TestOwnedEntityTypeBuilder<TEntity>,
IInfrastructure<OwnedEntityTypeBuilder>
where TEntity : class
Expand Down
18 changes: 18 additions & 0 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,24 @@ public abstract TestCollectionNavigationBuilder<TEntity, TRelatedEntity> HasMany
public abstract DataBuilder<TEntity> HasData(IEnumerable<TEntity> data);

public abstract DataBuilder<TEntity> HasData(IEnumerable<object> data);

public abstract TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(
Expression<Func<TEntity, TDiscriminator>> propertyExpression);

public abstract TestDiscriminatorBuilder<TDiscriminator> HasDiscriminator<TDiscriminator>(string propertyName);

public abstract TestEntityTypeBuilder<TEntity> HasNoDiscriminator();
}

public abstract class TestDiscriminatorBuilder<TDiscriminator>
{
public abstract TestDiscriminatorBuilder<TDiscriminator> HasValue(TDiscriminator value);

public abstract TestDiscriminatorBuilder<TDiscriminator> HasValue<TEntity>(TDiscriminator value);

public abstract TestDiscriminatorBuilder<TDiscriminator> HasValue(Type entityType, TDiscriminator value);

public abstract TestDiscriminatorBuilder<TDiscriminator> HasValue(string entityTypeName, TDiscriminator value);
}

public abstract class TestOwnedEntityTypeBuilder<TEntity>
Expand Down

0 comments on commit 652e791

Please sign in to comment.