Skip to content

Commit

Permalink
Clean up Metadata API
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd committed Aug 21, 2019
1 parent 3fe29b0 commit 85a93ec
Show file tree
Hide file tree
Showing 23 changed files with 402 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ private static void TryUniquifyTableNames(

private static bool ShouldUniquify(IConventionEntityType entityType, ICollection<IConventionEntityType> entityTypes)
{
var rootType = entityType.RootType();
var rootType = entityType.GetRootType();
var pkProperty = entityType.FindPrimaryKey()?.Properties[0];
var rootSharedTableType = pkProperty?.FindSharedTableRootPrimaryKeyProperty()?.DeclaringEntityType;

foreach (var otherEntityType in entityTypes)
{
if (rootSharedTableType == otherEntityType
|| rootType == otherEntityType.RootType())
|| rootType == otherEntityType.GetRootType())
{
return false;
}
Expand Down
19 changes: 18 additions & 1 deletion src/EFCore/Extensions/ConventionEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ public static class ConventionEntityTypeExtensions
/// <returns>
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
/// </returns>
public static IConventionEntityType GetRootType([NotNull] this IConventionEntityType entityType)
=> (IConventionEntityType)((IEntityType)entityType).GetRootType();

/// <summary>
/// Gets the root base type for a given entity type.
/// </summary>
/// <param name="entityType"> The type to find the root of. </param>
/// <returns>
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
/// </returns>
[Obsolete("Use GetRootType")]
public static IConventionEntityType RootType([NotNull] this IConventionEntityType entityType)
=> (IConventionEntityType)((IEntityType)entityType).GetRootType();

Expand Down Expand Up @@ -216,7 +227,6 @@ public static IConventionKey RemoveKey(
[NotNull] IReadOnlyList<IConventionProperty> properties)
=> ((EntityType)entityType).RemoveKey(properties);


/// <summary>
/// <para>
/// Gets all foreign keys declared on the given <see cref="IConventionEntityType" />.
Expand Down Expand Up @@ -611,6 +621,13 @@ public static void SetDefiningQuery(
public static ConfigurationSource? GetDefiningQueryConfigurationSource([NotNull] this IConventionEntityType entityType)
=> entityType.FindAnnotation(CoreAnnotationNames.DefiningQuery)?.GetConfigurationSource();

/// <summary>
/// Returns the <see cref="IConventionProperty" /> that will be used for storing a discriminator value.
/// </summary>
/// <param name="entityType"> The entity type to get the discriminator property for. </param>
public static IConventionProperty GetDiscriminatorProperty([NotNull] this IConventionEntityType entityType)
=> (IConventionProperty)((IEntityType)entityType).GetDiscriminatorProperty();

/// <summary>
/// Sets the <see cref="IProperty" /> that will be used for storing a discriminator value.
/// </summary>
Expand Down
34 changes: 32 additions & 2 deletions src/EFCore/Extensions/ConventionModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
Expand All @@ -17,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore
public static class ConventionModelExtensions
{
/// <summary>
/// Gets the entity that maps the given entity class. Returns null if no entity type with the given name is found.
/// Gets the entity that maps the given entity class. Returns <c>null</c> if no entity type with the given name is found.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="type"> The type to find the corresponding entity type for. </param>
Expand All @@ -27,7 +28,7 @@ public static IConventionEntityType FindEntityType([NotNull] this IConventionMod

/// <summary>
/// Gets the entity type for the given name, defining navigation name
/// and the defining entity type. Returns null if no matching entity type is found.
/// and the defining entity type. Returns <c>null</c> if no matching entity type is found.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="type"> The type of the entity type to find. </param>
Expand All @@ -41,6 +42,26 @@ public static IConventionEntityType FindEntityType(
[NotNull] IConventionEntityType definingEntityType)
=> (IConventionEntityType)((IModel)model).FindEntityType(type, definingNavigationName, definingEntityType);

/// <summary>
/// Gets the entity types matching the given type.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="type"> The type of the entity type to find. </param>
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IConventionEntityType> GetEntityTypes([NotNull] this IConventionModel model, [NotNull] Type type)
=> ((Model)model).GetEntityTypes(type);

/// <summary>
/// Gets the entity types matching the given name.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="name"> The name of the entity type to find. </param>
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IConventionEntityType> GetEntityTypes([NotNull] this IConventionModel model, [NotNull] string name)
=> ((Model)model).GetEntityTypes(name);

/// <summary>
/// Removes an entity type without a defining navigation from the model.
/// </summary>
Expand Down Expand Up @@ -272,5 +293,14 @@ public static void AddIgnored([NotNull] this IConventionModel model, [NotNull] T
=> Check.NotNull((Model)model, nameof(model)).AddIgnored(
Check.NotNull(clrType, nameof(clrType)),
fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);

/// <summary>
/// Forces post-processing on the model such that it is ready for use by the runtime. This post
/// processing happens automatically when using <see cref="DbContext.OnModelCreating"/>; this method allows it to be run
/// explicitly in cases where the automatic execution is not possible.
/// </summary>
/// <param name="model"> The model to finalize. </param>
/// <returns> The finalized <see cref="IModel" />. </returns>
public static IModel FinalizeModel([NotNull] this IConventionModel model) => (Model)model.FinalizeModel();
}
}
8 changes: 8 additions & 0 deletions src/EFCore/Extensions/ConventionPropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ public static IConventionKey FindContainingPrimaryKey([NotNull] this IConvention
public static IEnumerable<IConventionKey> GetContainingKeys([NotNull] this IConventionProperty property)
=> ((Property)property).GetContainingKeys();

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for <see cref="PropertyExtensions.FindTypeMapping(IProperty)" />.
/// </summary>
/// <param name="property"> The property. </param>
/// <returns> The <see cref="ConfigurationSource" /> for <see cref="PropertyExtensions.FindTypeMapping(IProperty)" />. </returns>
public static ConfigurationSource? GetTypeMappingConfigurationSource([NotNull] this IConventionProperty property)
=> property.FindAnnotation(CoreAnnotationNames.TypeMapping)?.GetConfigurationSource();

/// <summary>
/// Sets the maximum length of data that is allowed in this property. For example, if the property is a <see cref="string" /> '
/// then this is the maximum number of characters.
Expand Down
37 changes: 18 additions & 19 deletions src/EFCore/Extensions/MutableEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ public static class MutableEntityTypeExtensions
/// <returns>
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
/// </returns>
public static IMutableEntityType GetRootType([NotNull] this IMutableEntityType entityType)
=> (IMutableEntityType)((IEntityType)entityType).GetRootType();

/// <summary>
/// Gets the root base type for a given entity type.
/// </summary>
/// <param name="entityType"> The type to find the root of. </param>
/// <returns>
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
/// </returns>
[Obsolete("Use GetRootType")]
public static IMutableEntityType RootType([NotNull] this IMutableEntityType entityType)
=> (IMutableEntityType)((IEntityType)entityType).GetRootType();

Expand Down Expand Up @@ -497,25 +508,6 @@ public static IMutableIndex RemoveIndex(
[NotNull] IReadOnlyList<IMutableProperty> properties)
=> ((EntityType)entityType).RemoveIndex(properties);

/// <summary>
/// <para>
/// Sets the <see cref="PropertyAccessMode" /> to use for properties of all entity types
/// in this model.
/// </para>
/// <para>
/// Note that individual entity types can override this access mode, and individual properties of
/// entity types can override the access mode set on the entity type. The value set here will
/// be used for any property for which no override has been specified.
/// </para>
/// </summary>
/// <param name="entityType"> The entity type to set the access mode for. </param>
/// <param name="propertyAccessMode"> The <see cref="PropertyAccessMode" />, or <c>null</c> to clear the mode set.</param>
public static void SetPropertyAccessMode(
[NotNull] this IConventionEntityType entityType,
PropertyAccessMode? propertyAccessMode)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType()
.SetPropertyAccessMode(propertyAccessMode, ConfigurationSource.Explicit);

/// <summary>
/// Sets the change tracking strategy to use for this entity type. This strategy indicates how the
/// context detects changes to properties for an instance of the entity type.
Expand Down Expand Up @@ -550,6 +542,13 @@ public static void SetDefiningQuery(
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType()
.SetDefiningQuery(definingQuery, ConfigurationSource.Explicit);

/// <summary>
/// Returns the <see cref="IMutableProperty" /> that will be used for storing a discriminator value.
/// </summary>
/// <param name="entityType"> The entity type to get the discriminator property for. </param>
public static IMutableProperty GetDiscriminatorProperty([NotNull] this IMutableEntityType entityType)
=> (IMutableProperty)((IEntityType)entityType).GetDiscriminatorProperty();

/// <summary>
/// Sets the <see cref="IProperty" /> that will be used for storing a discriminator value.
/// </summary>
Expand Down
23 changes: 22 additions & 1 deletion src/EFCore/Extensions/MutableModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
Expand Down Expand Up @@ -41,6 +42,26 @@ public static IMutableEntityType FindEntityType(
[NotNull] IMutableEntityType definingEntityType)
=> (IMutableEntityType)((IModel)model).FindEntityType(type, definingNavigationName, definingEntityType);

/// <summary>
/// Gets the entity types matching the given type.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="type"> The type of the entity type to find. </param>
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IMutableEntityType> GetEntityTypes([NotNull] this IMutableModel model, [NotNull] Type type)
=> ((Model)model).GetEntityTypes(type);

/// <summary>
/// Gets the entity types matching the given name.
/// </summary>
/// <param name="model"> The model to find the entity type in. </param>
/// <param name="name"> The name of the entity type to find. </param>
/// <returns> The entity types found. </returns>
[DebuggerStepThrough]
public static IReadOnlyCollection<IMutableEntityType> GetEntityTypes([NotNull] this IMutableModel model, [NotNull] string name)
=> ((Model)model).GetEntityTypes(name);

/// <summary>
/// Removes an entity type from the model.
/// </summary>
Expand Down Expand Up @@ -223,6 +244,6 @@ public static void RemoveOwned([NotNull] this IMutableModel model, [NotNull] Typ
/// </summary>
/// <param name="model"> The model to finalize. </param>
/// <returns> The finalized <see cref="IModel" />. </returns>
public static IModel FinalizeModel([NotNull] this IMutableModel model) => model.AsModel().FinalizeModel();
public static IModel FinalizeModel([NotNull] this IMutableModel model) => (Model)model.FinalizeModel();
}
}
10 changes: 0 additions & 10 deletions src/EFCore/Extensions/NavigationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ namespace Microsoft.EntityFrameworkCore
/// </summary>
public static class NavigationExtensions
{
/// <summary>
/// Creates a new <see cref="MemberIdentity" /> for the given navigation property.
/// </summary>
/// <param name="navigation"> The navigation property. </param>
/// <returns> The new <see cref="MemberIdentity" />. </returns>
public static MemberIdentity CreateMemberIdentity([CanBeNull] this INavigation navigation)
=> navigation?.GetIdentifyingMemberInfo() == null
? MemberIdentity.Create(navigation?.Name)
: MemberIdentity.Create(navigation.GetIdentifyingMemberInfo());

/// <summary>
/// Gets the <see cref="IClrCollectionAccessor" /> for this navigation property, which must be a collection
/// navigation.
Expand Down
8 changes: 0 additions & 8 deletions src/EFCore/Extensions/PropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,6 @@ public static CoreTypeMapping FindTypeMapping([NotNull] this IProperty property)
public static CoreTypeMapping FindMapping([NotNull] this IProperty property)
=> property.FindTypeMapping();

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for <see cref="FindTypeMapping(IProperty)" />.
/// </summary>
/// <param name="property"> The property. </param>
/// <returns> The <see cref="ConfigurationSource" /> for <see cref="FindTypeMapping(IProperty)" />. </returns>
public static ConfigurationSource? GetTypeMappingConfigurationSource([NotNull] this IConventionProperty property)
=> property.FindAnnotation(CoreAnnotationNames.TypeMapping)?.GetConfigurationSource();

/// <summary>
/// Finds the first principal property that the given property is constrained by
/// if the given property is part of a foreign key.
Expand Down
1 change: 0 additions & 1 deletion src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged(
return;
}

var rootTypeBuilder = entityType.RootType().Builder;
var rootTypeBuilder = entityType.GetRootType().Builder;
discriminator = rootTypeBuilder?.HasDiscriminator(typeof(string));

if (newBaseType.BaseType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ private static IReadOnlyList<RelationshipCandidate> RemoveInheritedInverseNaviga
return relationshipCandidates;
}

var relationshipCandidatesByRoot = relationshipCandidates.GroupBy(r => r.TargetTypeBuilder.Metadata.RootType())
var relationshipCandidatesByRoot = relationshipCandidates.GroupBy(r => r.TargetTypeBuilder.Metadata.GetRootType())
.ToDictionary(g => g.Key, g => g.ToList());
foreach (var relationshipCandidatesHierarchy in relationshipCandidatesByRoot.Values)
{
Expand Down
5 changes: 5 additions & 0 deletions src/EFCore/Metadata/IConventionEntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public interface IConventionEntityType : IEntityType, IConventionTypeBase
/// </summary>
new IConventionEntityType BaseType { get; }

/// <summary>
/// Gets the defining entity type.
/// </summary>
new IConventionEntityType DefiningEntityType { get; }

/// <summary>
/// Gets a value indicating whether the entity type has no keys.
/// If <c>true</c> it will only be usable for queries.
Expand Down
1 change: 1 addition & 0 deletions src/EFCore/Metadata/IMutableAnnotatable.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;

Expand Down
5 changes: 5 additions & 0 deletions src/EFCore/Metadata/IMutableEntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public interface IMutableEntityType : IEntityType, IMutableTypeBase
/// </summary>
new IMutableEntityType BaseType { get; [param: CanBeNull] set; }

/// <summary>
/// Gets the defining entity type.
/// </summary>
new IMutableEntityType DefiningEntityType { get; }

/// <summary>
/// Gets or sets a value indicating whether the entity type has no keys.
/// If set to <c>true</c> it will only be usable for queries.
Expand Down
22 changes: 22 additions & 0 deletions src/EFCore/Metadata/Internal/EntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2615,6 +2615,28 @@ IEntityType IEntityType.DefiningEntityType
[DebuggerStepThrough] get => DefiningEntityType;
}

/// <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>
IMutableEntityType IMutableEntityType.DefiningEntityType
{
[DebuggerStepThrough] get => DefiningEntityType;
}

/// <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>
IConventionEntityType IConventionEntityType.DefiningEntityType
{
[DebuggerStepThrough] get => DefiningEntityType;
}

/// <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
Expand Down
Loading

0 comments on commit 85a93ec

Please sign in to comment.