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

Change some metadata extension methods into DIM properties and annotate for nullability #23361

Merged
1 commit merged into from
Nov 18, 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
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public virtual InternalEntityEntry Create(

private static InternalEntityEntry NewInternalEntityEntry(IStateManager stateManager, IEntityType entityType, object entity)
{
if (!entityType.HasClrType())
if (!entityType.HasClrType)
{
return new InternalShadowEntityEntry(stateManager, entityType);
}
Expand All @@ -66,7 +66,7 @@ private static InternalEntityEntry NewInternalEntityEntry(
object entity,
in ValueBuffer valueBuffer)
{
return !entityType.HasClrType()
return !entityType.HasClrType
? new InternalShadowEntityEntry(stateManager, entityType, valueBuffer)
: entityType.ShadowPropertyCount() > 0
? (InternalEntityEntry)new InternalMixedEntityEntry(stateManager, entityType, entity, valueBuffer)
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/ChangeTracking/Internal/StateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ public virtual InternalEntityEntry CreateEntry(IDictionary<string, object> value
}

var valueBuffer = new ValueBuffer(valuesArray);
var entity = entityType.HasClrType()
var entity = entityType.HasClrType
? EntityMaterializerSource.GetMaterializer(entityType)(new MaterializationContext(valueBuffer, Context))
: null;

Expand Down
13 changes: 6 additions & 7 deletions src/EFCore/Extensions/EntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,14 +357,14 @@ public static string FullName([NotNull] this ITypeBase type)
var root = entityType;
while (true)
{
var definingNavigationName = root.DefiningNavigationName;
if (definingNavigationName == null)
if (!root.HasDefiningNavigation())
{
break;
}

// TODO-NULLABLE: Put MemberNotNull on DefiningNavigationName (or check HasDefiningNavigation) when we target net5.0
root = root.DefiningEntityType!;
var definingNavigationName = root.DefiningNavigationName;

root = root.DefiningEntityType;
path.Push("#");
path.Push(definingNavigationName);
path.Push(".");
Expand Down Expand Up @@ -410,7 +410,7 @@ public static string ShortName([NotNull] this ITypeBase type)
/// <returns> <see langword="true" /> if this entity type has a defining navigation. </returns>
[DebuggerStepThrough]
public static bool HasDefiningNavigation([NotNull] this IEntityType entityType)
=> entityType.DefiningEntityType != null;
=> entityType.HasDefiningNavigation();

/// <summary>
/// Gets a value indicating whether this entity type is owned by another entity type.
Expand Down Expand Up @@ -585,8 +585,7 @@ public static IEnumerable<IForeignKey> GetDeclaredReferencingForeignKeys([NotNul
return null;
}

// TODO-NULLABLE: Put two MemberNotNulls on HasDefiningNavigation when we target net5.0
var definingNavigation = entityType.DefiningEntityType!.FindNavigation(entityType.DefiningNavigationName!);
var definingNavigation = entityType.DefiningEntityType.FindNavigation(entityType.DefiningNavigationName);
return definingNavigation?.TargetEntityType == entityType ? definingNavigation : null;
}

Expand Down
6 changes: 3 additions & 3 deletions src/EFCore/Infrastructure/ModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ protected virtual void ValidatePropertyMapping(
entityType.DisplayName(), unmappedProperty.Name, unmappedProperty.ClrType.ShortDisplayName()));
}

if (!entityType.HasClrType())
if (!entityType.HasClrType)
{
continue;
}
Expand Down Expand Up @@ -375,7 +375,7 @@ protected virtual void ValidateNoShadowEntities(
{
Check.NotNull(model, nameof(model));

var firstShadowEntity = model.GetEntityTypes().FirstOrDefault(entityType => !entityType.HasClrType());
var firstShadowEntity = model.GetEntityTypes().FirstOrDefault(entityType => !entityType.HasClrType);
if (firstShadowEntity != null)
{
throw new InvalidOperationException(
Expand Down Expand Up @@ -745,7 +745,7 @@ protected virtual void ValidateOwnership(
ownership.PrincipalEntityType.DisplayName()));
}
}
else if (entityType.HasClrType()
else if (entityType.HasClrType
&& ((IMutableModel)model).IsOwned(entityType.ClrType))
{
throw new InvalidOperationException(CoreStrings.OwnerlessOwnedType(entityType.DisplayName()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public virtual void ProcessEntityTypeAdded(
foreach (var directlyDerivedType in model.GetEntityTypes())
{
if (directlyDerivedType != entityType
&& directlyDerivedType.HasClrType()
&& directlyDerivedType.HasClrType
&& !directlyDerivedType.HasSharedClrType
&& !directlyDerivedType.HasDefiningNavigation()
&& model.FindIsOwnedConfigurationSource(directlyDerivedType.ClrType) == null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ private static TAttribute GetAttribute<TAttribute>(MemberInfo memberInfo)
private MemberInfo FindForeignKeyAttributeOnProperty(IConventionEntityType entityType, string navigationName)
{
if (string.IsNullOrWhiteSpace(navigationName)
|| !entityType.HasClrType())
|| !entityType.HasClrType)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public virtual void ProcessEntityTypeAdded(
IConventionContext<IConventionEntityTypeBuilder> context)
{
var entityType = entityTypeBuilder.Metadata;
if (!entityType.HasClrType())
if (!entityType.HasClrType)
{
return;
}
Expand Down Expand Up @@ -162,7 +162,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged(
IConventionContext<IConventionEntityType> context)
{
var entityType = entityTypeBuilder.Metadata;
if (!entityType.HasClrType()
if (!entityType.HasClrType
|| entityTypeBuilder.Metadata.BaseType != newBaseType)
{
return;
Expand Down Expand Up @@ -336,7 +336,7 @@ private static IEnumerable<TCustomAttribute> GetAttributes<TCustomAttribute>(
[NotNull] MemberInfo memberInfo)
where TCustomAttribute : Attribute
{
if (!entityType.HasClrType()
if (!entityType.HasClrType
|| memberInfo == null)
{
return Enumerable.Empty<TCustomAttribute>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private void ProcessNavigation(IConventionNavigationBuilder navigationBuilder)
}

private bool IsNonNullable(IConventionModelBuilder modelBuilder, IConventionNavigation navigation)
=> navigation.DeclaringEntityType.HasClrType()
=> navigation.DeclaringEntityType.HasClrType
&& navigation.DeclaringEntityType.GetRuntimeProperties().Find(navigation.Name) is PropertyInfo propertyInfo
&& IsNonNullableReferenceType(modelBuilder, propertyInfo);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public virtual void ProcessEntityTypeAdded(
Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder));

var entityType = entityTypeBuilder.Metadata;
if (!entityType.HasClrType())
if (!entityType.HasClrType)
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected override void ProcessEntityTypeAdded(
OwnedAttribute attribute,
IConventionContext<IConventionEntityTypeBuilder> context)
{
if (entityTypeBuilder.Metadata.HasClrType())
if (entityTypeBuilder.Metadata.HasClrType)
{
entityTypeBuilder.ModelBuilder.Owned(entityTypeBuilder.Metadata.ClrType, fromDataAnnotation: true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged(
private void Process(IConventionEntityTypeBuilder entityTypeBuilder)
{
var entityType = entityTypeBuilder.Metadata;
if (entityType.HasClrType())
if (entityType.HasClrType)
{
foreach (var propertyInfo in entityType.GetRuntimeProperties().Values)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public RelationshipDiscoveryConvention([NotNull] ProviderConventionSetBuilderDep

private void DiscoverRelationships(IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext context)
{
if (!entityTypeBuilder.Metadata.HasClrType()
if (!entityTypeBuilder.Metadata.HasClrType
|| entityTypeBuilder.ModelBuilder.IsIgnored(entityTypeBuilder.Metadata.ClrType))
{
return;
Expand Down Expand Up @@ -986,7 +986,7 @@ private ImmutableSortedDictionary<PropertyInfo, Type> GetNavigationCandidates(IC
}

var dictionaryBuilder = ImmutableSortedDictionary.CreateBuilder<PropertyInfo, Type>(MemberInfoNameComparer.Instance);
if (entityType.HasClrType())
if (entityType.HasClrType)
{
foreach (var propertyInfo in entityType.GetRuntimeProperties().Values.OrderBy(p => p.Name))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private void Process(IConventionEntityTypeBuilder entityTypeBuilder)
{
var entityType = entityTypeBuilder.Metadata;

if (!entityType.HasClrType())
if (!entityType.HasClrType)
{
return;
}
Expand Down
17 changes: 17 additions & 0 deletions src/EFCore/Metadata/IEntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
using CA = System.Diagnostics.CodeAnalysis;

#nullable enable

Expand All @@ -31,6 +32,22 @@ public interface IEntityType : ITypeBase
/// </summary>
IEntityType? DefiningEntityType { get; }

/// <summary>
/// Gets a value indicating whether this entity type has a defining navigation.
/// </summary>
/// <returns> <see langword="true" /> if this entity type has a defining navigation. </returns>
[CA.MemberNotNullWhen(true, nameof(DefiningNavigationName), nameof(DefiningEntityType))]
public bool HasDefiningNavigation()
{
if (DefiningEntityType != null)
{
Check.DebugAssert(DefiningNavigationName != null,
$"{nameof(DefiningEntityType)} is non-null but {nameof(DefiningNavigationName)} is null");
return true;
}
return false;
}

/// <summary>
/// Gets primary key for this entity type. Returns <see langword="null" /> if no primary key is defined.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/EFCore/Metadata/ITypeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using CA = System.Diagnostics.CodeAnalysis;

#nullable enable

Expand Down Expand Up @@ -35,9 +36,17 @@ public interface ITypeBase : IAnnotatable
/// </summary>
Type? ClrType { get; }

/// <summary>
/// Gets whether this entity type has an associated CLR type. An entity type without an associated CLR type is known as
/// a shadow type.
/// </summary>
[CA.MemberNotNullWhen(true, nameof(ClrType))]
public bool HasClrType => ClrType != null;

/// <summary>
/// Gets whether this entity type can share its ClrType with other entities.
/// </summary>
[CA.MemberNotNullWhen(true, nameof(ClrType))]
bool HasSharedClrType { get; }

/// <summary>
Expand Down
29 changes: 22 additions & 7 deletions src/EFCore/Metadata/Internal/EntityType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,22 @@ public virtual bool IsKeyless
/// </summary>
public virtual EntityType? DefiningEntityType { get; }

/// <summary>
/// Gets a value indicating whether this entity type has a defining navigation.
/// </summary>
/// <returns> <see langword="true" /> if this entity type has a defining navigation. </returns>
[CA.MemberNotNullWhen(true, nameof(DefiningNavigationName), nameof(DefiningEntityType))]
public virtual bool HasDefiningNavigation()
{
if (DefiningEntityType != null)
{
Check.DebugAssert(DefiningNavigationName != null,
$"{nameof(DefiningEntityType)} is non-null but {nameof(DefiningNavigationName)} is null");
return true;
}
return false;
}

/// <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 Expand Up @@ -306,7 +322,7 @@ public virtual void UpdateIsKeylessConfigurationSource(ConfigurationSource confi
return newBaseType;
}

if (this.HasDefiningNavigation())
if (HasDefiningNavigation())
{
throw new InvalidOperationException(CoreStrings.WeakDerivedType(this.DisplayName()));
}
Expand All @@ -318,15 +334,14 @@ public virtual void UpdateIsKeylessConfigurationSource(ConfigurationSource confi

if (newBaseType != null)
{
if (this.HasClrType())
if (HasClrType)
{
if (!newBaseType.HasClrType())
if (!newBaseType.HasClrType)
{
throw new InvalidOperationException(CoreStrings.NonClrBaseType(this.DisplayName(), newBaseType.DisplayName()));
}

// TODO-NULLABLE: Use MemberNotNullWhen on HasClrType when we target net5.0
if (!newBaseType.ClrType!.IsAssignableFrom(ClrType))
if (!newBaseType.ClrType.IsAssignableFrom(ClrType))
{
throw new InvalidOperationException(
CoreStrings.NotAssignableClrBaseType(
Expand All @@ -340,8 +355,8 @@ public virtual void UpdateIsKeylessConfigurationSource(ConfigurationSource confi
}
}

if (!this.HasClrType()
&& newBaseType.HasClrType())
if (!HasClrType
&& newBaseType.HasClrType)
{
throw new InvalidOperationException(CoreStrings.NonShadowBaseType(this.DisplayName(), newBaseType.DisplayName()));
}
Expand Down
8 changes: 4 additions & 4 deletions src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private InternalForeignKeyBuilder HasNavigations(

if (navigationToPrincipalName != null
&& navigationToPrincipal.Value.MemberInfo == null
&& dependentEntityType.HasClrType())
&& dependentEntityType.HasClrType)
{
var navigationProperty = FindCompatibleClrMember(
navigationToPrincipalName, dependentEntityType, principalEntityType, shouldThrow);
Expand All @@ -214,7 +214,7 @@ private InternalForeignKeyBuilder HasNavigations(

if (navigationToDependentName != null
&& navigationToDependent.Value.MemberInfo == null
&& principalEntityType.HasClrType())
&& principalEntityType.HasClrType)
{
var navigationProperty = FindCompatibleClrMember(
navigationToDependentName, principalEntityType, dependentEntityType, shouldThrow);
Expand Down Expand Up @@ -2266,13 +2266,13 @@ private InternalForeignKeyBuilder ReplaceForeignKey(
Check.DebugAssert(
navigationToPrincipal?.Name == null
|| navigationToPrincipal.Value.MemberInfo != null
|| !dependentEntityTypeBuilder.Metadata.HasClrType(),
|| !dependentEntityTypeBuilder.Metadata.HasClrType,
"Principal navigation check failed");

Check.DebugAssert(
navigationToDependent?.Name == null
|| navigationToDependent.Value.MemberInfo != null
|| !principalEntityTypeBuilder.Metadata.HasClrType(),
|| !principalEntityTypeBuilder.Metadata.HasClrType,
"Dependent navigation check failed");

Check.DebugAssert(
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Metadata/Internal/InternalModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ private InternalModelBuilder Ignore(in TypeIdentity type, ConfigurationSource co
var removed = false;
foreach (var entityType in Metadata.GetEntityTypes(name).ToList())
{
if (entityType.HasClrType())
if (entityType.HasClrType)
{
if (entityType.HasSharedClrType)
{
Expand Down
Loading