Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor model building perf improvements #22285

Merged
merged 1 commit into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/EFCore/Extensions/ConventionModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static class ConventionModelExtensions
/// <param name="type"> The type to find the corresponding entity type for. </param>
/// <returns> The entity type, or <see langword="null" /> if none if found. </returns>
public static IConventionEntityType FindEntityType([NotNull] this IConventionModel model, [NotNull] Type type)
=> (IConventionEntityType)((IModel)model).FindEntityType(type);
=> ((Model)model).FindEntityType(type);

/// <summary>
/// Gets the entity type for the given name, defining navigation name
Expand Down
6 changes: 3 additions & 3 deletions src/EFCore/Extensions/ModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static class ModelExtensions
/// <returns> The entity type, or <see langword="null" /> if none if found. </returns>
[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)));

/// <summary>
/// Gets the entity that maps the given entity class, where the class may be a proxy derived from the
Expand Down Expand Up @@ -87,7 +87,7 @@ public static IEntityType FindEntityType(
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IEntityType> GetEntityTypes([NotNull] this IModel model, [NotNull] Type type)
=> model.AsModel().GetEntityTypes(type);
=> ((Model)model).GetEntityTypes(type);

/// <summary>
/// Gets the entity types matching the given name.
Expand All @@ -97,7 +97,7 @@ public static IReadOnlyCollection<IEntityType> GetEntityTypes([NotNull] this IMo
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IEntityType> GetEntityTypes([NotNull] this IModel model, [NotNull] string name)
=> model.AsModel().GetEntityTypes(name);
=> ((Model)model).GetEntityTypes(name);

/// <summary>
/// Gets a value indicating whether the model contains a corresponding entity type with a defining navigation.
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Extensions/MutableModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static class MutableModelExtensions
/// <param name="type"> The type to find the corresponding entity type for. </param>
/// <returns> The entity type, or <see langword="null" /> if none if found. </returns>
public static IMutableEntityType FindEntityType([NotNull] this IMutableModel model, [NotNull] Type type)
=> (IMutableEntityType)((IModel)model).FindEntityType(type);
=> ((Model)model).FindEntityType(type);

/// <summary>
/// Gets the entity type for the given name, defining navigation name
Expand Down
29 changes: 14 additions & 15 deletions src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
Expand Down Expand Up @@ -33,18 +32,14 @@ protected InheritanceDiscoveryConventionBase([NotNull] ProviderConventionSetBuil
/// <param name="entityType"> The entity type. </param>
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;
}

Expand Down
26 changes: 23 additions & 3 deletions src/EFCore/Metadata/Internal/EntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,17 @@ public virtual ForeignKey FindForeignKey(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ForeignKey FindOwnership()
=> GetForeignKeys().FirstOrDefault(fk => fk.IsOwnership);
{
foreach (var foreignKey in GetForeignKeys())
{
if (foreignKey.IsOwnership)
{
return foreignKey;
}
}

return null;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand All @@ -1160,7 +1170,17 @@ public virtual ForeignKey FindOwnership()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ForeignKey FindDeclaredOwnership()
=> GetDeclaredForeignKeys().FirstOrDefault(fk => fk.IsOwnership);
{
foreach (var foreignKey in _foreignKeys)
{
if (foreignKey.IsOwnership)
{
return foreignKey;
}
}

return null;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand All @@ -1180,7 +1200,7 @@ public virtual IEnumerable<ForeignKey> GetDeclaredForeignKeys()
public virtual IEnumerable<ForeignKey> GetDerivedForeignKeys()
=> _directlyDerivedTypes.Count == 0
? Enumerable.Empty<ForeignKey>()
: GetDerivedTypes().SelectMany(et => et.GetDeclaredForeignKeys());
: GetDerivedTypes().SelectMany(et => et._foreignKeys);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
5 changes: 4 additions & 1 deletion src/EFCore/Metadata/Internal/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,12 @@ public virtual EntityType FindEntityType([NotNull] Type type)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
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;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down