diff --git a/src/EFCore/Extensions/ConventionModelExtensions.cs b/src/EFCore/Extensions/ConventionModelExtensions.cs
index 392115faece..6a2061d3937 100644
--- a/src/EFCore/Extensions/ConventionModelExtensions.cs
+++ b/src/EFCore/Extensions/ConventionModelExtensions.cs
@@ -24,7 +24,7 @@ public static class ConventionModelExtensions
/// The type to find the corresponding entity type for.
/// The entity type, or if none if found.
public static IConventionEntityType FindEntityType([NotNull] this IConventionModel model, [NotNull] Type type)
- => (IConventionEntityType)((IModel)model).FindEntityType(type);
+ => ((Model)model).FindEntityType(type);
///
/// Gets the entity type for the given name, defining navigation name
diff --git a/src/EFCore/Extensions/ModelExtensions.cs b/src/EFCore/Extensions/ModelExtensions.cs
index 90386515e27..ecd6bad495c 100644
--- a/src/EFCore/Extensions/ModelExtensions.cs
+++ b/src/EFCore/Extensions/ModelExtensions.cs
@@ -30,7 +30,7 @@ public static class ModelExtensions
/// The entity type, or if none if found.
[DebuggerStepThrough]
public static IEntityType FindEntityType([NotNull] this IModel model, [NotNull] Type type)
- => ((Model)Check.NotNull(model, nameof(model))).FindEntityType(Check.NotNull(type, nameof(type)));
+ => ((Model)model).FindEntityType(Check.NotNull(type, nameof(type)));
///
/// Gets the entity that maps the given entity class, where the class may be a proxy derived from the
@@ -87,7 +87,7 @@ public static IEntityType FindEntityType(
/// The entity types found.
[DebuggerStepThrough]
public static IReadOnlyCollection GetEntityTypes([NotNull] this IModel model, [NotNull] Type type)
- => model.AsModel().GetEntityTypes(type);
+ => ((Model)model).GetEntityTypes(type);
///
/// Gets the entity types matching the given name.
@@ -97,7 +97,7 @@ public static IReadOnlyCollection GetEntityTypes([NotNull] this IMo
/// The entity types found.
[DebuggerStepThrough]
public static IReadOnlyCollection GetEntityTypes([NotNull] this IModel model, [NotNull] string name)
- => model.AsModel().GetEntityTypes(name);
+ => ((Model)model).GetEntityTypes(name);
///
/// Gets a value indicating whether the model contains a corresponding entity type with a defining navigation.
diff --git a/src/EFCore/Extensions/MutableModelExtensions.cs b/src/EFCore/Extensions/MutableModelExtensions.cs
index 51e7383c44e..24371118172 100644
--- a/src/EFCore/Extensions/MutableModelExtensions.cs
+++ b/src/EFCore/Extensions/MutableModelExtensions.cs
@@ -26,7 +26,7 @@ public static class MutableModelExtensions
/// The type to find the corresponding entity type for.
/// The entity type, or if none if found.
public static IMutableEntityType FindEntityType([NotNull] this IMutableModel model, [NotNull] Type type)
- => (IMutableEntityType)((IModel)model).FindEntityType(type);
+ => ((Model)model).FindEntityType(type);
///
/// Gets the entity type for the given name, defining navigation name
diff --git a/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs
index 24261c47c78..a7cd632ed2d 100644
--- a/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs
+++ b/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs
@@ -38,27 +38,26 @@ public virtual void ProcessEntityTypeAdded(
if (clrType == null
|| entityType.HasSharedClrType
|| entityType.HasDefiningNavigation()
- || entityType.FindDeclaredOwnership() != null
- || entityType.Model.FindIsOwnedConfigurationSource(clrType) != null)
+ || entityType.Model.FindIsOwnedConfigurationSource(clrType) != null
+ || entityType.FindOwnership() != null)
{
return;
}
var model = entityType.Model;
- var directlyDerivedTypes = model.GetEntityTypes().Where(
- t => t != entityType
- && t.HasClrType()
- && !t.HasDefiningNavigation()
- && t.FindDeclaredOwnership() == null
- && model.FindIsOwnedConfigurationSource(t.ClrType) == null
- && ((t.BaseType == null && clrType.IsAssignableFrom(t.ClrType))
- || (t.BaseType == entityType.BaseType && FindClosestBaseType(t) == entityType))
- && !t.HasSharedClrType)
- .ToList();
-
- foreach (var directlyDerivedType in directlyDerivedTypes)
+ foreach (var directlyDerivedType in model.GetEntityTypes())
{
- directlyDerivedType.Builder.HasBaseType(entityType);
+ if (directlyDerivedType != entityType
+ && directlyDerivedType.HasClrType()
+ && !directlyDerivedType.HasSharedClrType
+ && !directlyDerivedType.HasDefiningNavigation()
+ && model.FindIsOwnedConfigurationSource(directlyDerivedType.ClrType) == null
+ && directlyDerivedType.FindDeclaredOwnership() == null
+ && ((directlyDerivedType.BaseType == null && clrType.IsAssignableFrom(directlyDerivedType.ClrType))
+ || (directlyDerivedType.BaseType == entityType.BaseType && FindClosestBaseType(directlyDerivedType) == entityType)))
+ {
+ directlyDerivedType.Builder.HasBaseType(entityType);
+ }
}
}
}
diff --git a/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs b/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs
index 037edd439ea..bc25a3b36bd 100644
--- a/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs
+++ b/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs
@@ -3,7 +3,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
-using Microsoft.EntityFrameworkCore.Utilities;
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
@@ -33,18 +32,14 @@ protected InheritanceDiscoveryConventionBase([NotNull] ProviderConventionSetBuil
/// The entity type.
protected virtual IConventionEntityType FindClosestBaseType([NotNull] IConventionEntityType entityType)
{
- Check.NotNull(entityType, nameof(entityType));
-
- var clrType = entityType.ClrType;
- Check.NotNull(clrType, nameof(entityType.ClrType));
-
- var baseType = clrType.BaseType;
+ var baseType = entityType.ClrType.BaseType;
+ var model = entityType.Model;
IConventionEntityType baseEntityType = null;
-
while (baseType != null
- && baseEntityType == null)
+ && baseEntityType == null
+ && baseType != typeof(object))
{
- baseEntityType = entityType.Model.FindEntityType(baseType);
+ baseEntityType = model.FindEntityType(baseType);
baseType = baseType.BaseType;
}
diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs
index 47ea1f077af..0d43c6489cd 100644
--- a/src/EFCore/Metadata/Internal/EntityType.cs
+++ b/src/EFCore/Metadata/Internal/EntityType.cs
@@ -1151,7 +1151,17 @@ public virtual ForeignKey FindForeignKey(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual ForeignKey FindOwnership()
- => GetForeignKeys().FirstOrDefault(fk => fk.IsOwnership);
+ {
+ foreach (var foreignKey in GetForeignKeys())
+ {
+ if (foreignKey.IsOwnership)
+ {
+ return foreignKey;
+ }
+ }
+
+ return null;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1160,7 +1170,17 @@ public virtual ForeignKey FindOwnership()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual ForeignKey FindDeclaredOwnership()
- => GetDeclaredForeignKeys().FirstOrDefault(fk => fk.IsOwnership);
+ {
+ foreach (var foreignKey in _foreignKeys)
+ {
+ if (foreignKey.IsOwnership)
+ {
+ return foreignKey;
+ }
+ }
+
+ return null;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1180,7 +1200,7 @@ public virtual IEnumerable GetDeclaredForeignKeys()
public virtual IEnumerable GetDerivedForeignKeys()
=> _directlyDerivedTypes.Count == 0
? Enumerable.Empty()
- : GetDerivedTypes().SelectMany(et => et.GetDeclaredForeignKeys());
+ : GetDerivedTypes().SelectMany(et => et._foreignKeys);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs
index e5274c68234..dcf73d493cc 100644
--- a/src/EFCore/Metadata/Internal/Model.cs
+++ b/src/EFCore/Metadata/Internal/Model.cs
@@ -285,9 +285,12 @@ public virtual EntityType FindEntityType([NotNull] Type type)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual EntityType FindEntityType([NotNull] string name)
- => _entityTypes.TryGetValue(Check.NotEmpty(name, nameof(name)), out var entityType)
+ {
+ Check.DebugAssert(!string.IsNullOrEmpty(name), "name is null or empty");
+ return _entityTypes.TryGetValue(name, out var entityType)
? entityType
: null;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to