diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs index 5892fd4f046..90e85837f1f 100644 --- a/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs +++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs @@ -21,7 +21,7 @@ public static class CosmosNavigationExtensions /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static bool IsEmbedded([NotNull] this INavigation navigation) - => !navigation.IsDependentToPrincipal() + => !navigation.IsOnDependent && !navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot(); } } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs index 78b7d5a9651..650f5c1aa79 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs @@ -235,14 +235,14 @@ protected override Expression VisitMember(MemberExpression memberExpression) { case EntityProjectionExpression entityProjection: return new EntityShaperExpression( - navigation.GetTargetType(), + navigation.TargetEntityType, Expression.Convert(Expression.Convert(entityProjection, typeof(object)), typeof(ValueBuffer)), nullable: true); case ObjectArrayProjectionExpression objectArrayProjectionExpression: { var innerShaperExpression = new EntityShaperExpression( - navigation.GetTargetType(), + navigation.TargetEntityType, Expression.Convert( Expression.Convert(objectArrayProjectionExpression.InnerProjection, typeof(object)), typeof(ValueBuffer)), nullable: true); @@ -343,14 +343,14 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp { case EntityProjectionExpression entityProjection: return new EntityShaperExpression( - navigation.GetTargetType(), + navigation.TargetEntityType, Expression.Convert(Expression.Convert(entityProjection, typeof(object)), typeof(ValueBuffer)), nullable: true); case ObjectArrayProjectionExpression objectArrayProjectionExpression: { var innerShaperExpression = new EntityShaperExpression( - navigation.GetTargetType(), + navigation.TargetEntityType, Expression.Convert( Expression.Convert(objectArrayProjectionExpression.InnerProjection, typeof(object)), typeof(ValueBuffer)), nullable: true); diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs index cd26f2742a1..358cec4d816 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs @@ -213,7 +213,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp var lambda = (LambdaExpression)methodCallExpression.Arguments[1]; if (lambda.Body is IncludeExpression includeExpression) { - if (includeExpression.Navigation.IsDependentToPrincipal() + if (includeExpression.Navigation.IsOnDependent || includeExpression.Navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot()) { throw new InvalidOperationException( @@ -285,14 +285,14 @@ protected override Expression VisitExtension(Expression extensionExpression) var navigation = collectionShaperExpression.Navigation; return Expression.Call( - _populateCollectionMethodInfo.MakeGenericMethod(navigation.GetTargetType().ClrType, navigation.ClrType), + _populateCollectionMethodInfo.MakeGenericMethod(navigation.TargetEntityType.ClrType, navigation.ClrType), Expression.Constant(navigation.GetCollectionAccessor()), entities); } case IncludeExpression includeExpression: { - if (includeExpression.Navigation.IsDependentToPrincipal() + if (includeExpression.Navigation.IsOnDependent || includeExpression.Navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot()) { throw new InvalidOperationException( @@ -359,14 +359,14 @@ private void AddInclude( Expression instanceVariable) { var navigation = includeExpression.Navigation; - var includeMethod = navigation.IsCollection() ? _includeCollectionMethodInfo : _includeReferenceMethodInfo; + var includeMethod = navigation.IsCollection ? _includeCollectionMethodInfo : _includeReferenceMethodInfo; var includingClrType = navigation.DeclaringEntityType.ClrType; - var relatedEntityClrType = navigation.GetTargetType().ClrType; + var relatedEntityClrType = navigation.TargetEntityType.ClrType; var entityEntryVariable = _trackQueryResults ? shaperBlock.Variables.Single(v => v.Type == typeof(InternalEntityEntry)) : (Expression)Expression.Constant(null, typeof(InternalEntityEntry)); var concreteEntityTypeVariable = shaperBlock.Variables.Single(v => v.Type == typeof(IEntityType)); - var inverseNavigation = navigation.FindInverse(); + var inverseNavigation = navigation.Inverse; var fixup = GenerateFixup( includingClrType, relatedEntityClrType, navigation, inverseNavigation); var initialize = GenerateInitialize(includingClrType, navigation); @@ -398,7 +398,7 @@ private static void IncludeReference( INavigation navigation, INavigation inverseNavigation, Action fixup, - Action initialize) + Action _) { if (entity == null || !navigation.DeclaringEntityType.IsAssignableFrom(entityType)) @@ -414,7 +414,7 @@ private static void IncludeReference( { fixup(includingEntity, relatedEntity); if (inverseNavigation != null - && !inverseNavigation.IsCollection()) + && !inverseNavigation.IsCollection) { SetIsLoadedNoTracking(relatedEntity, inverseNavigation); } @@ -503,7 +503,7 @@ private static Delegate GenerateFixup( var relatedEntityParameter = Expression.Parameter(relatedEntityType); var expressions = new List { - navigation.IsCollection() + navigation.IsCollection ? AddToCollectionNavigation(entityParameter, relatedEntityParameter, navigation) : AssignReferenceNavigation(entityParameter, relatedEntityParameter, navigation) }; @@ -511,7 +511,7 @@ private static Delegate GenerateFixup( if (inverseNavigation != null) { expressions.Add( - inverseNavigation.IsCollection() + inverseNavigation.IsCollection ? AddToCollectionNavigation(relatedEntityParameter, entityParameter, inverseNavigation) : AssignReferenceNavigation(relatedEntityParameter, entityParameter, inverseNavigation)); } @@ -524,7 +524,7 @@ private static Delegate GenerateInitialize( Type entityType, INavigation navigation) { - if (!navigation.IsCollection()) + if (!navigation.IsCollection) { return null; } diff --git a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs index 49d6022914c..46bbe9f9dd4 100644 --- a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs @@ -152,14 +152,14 @@ public virtual Expression BindNavigation([NotNull] INavigation navigation, bool if (!_navigationExpressionsCache.TryGetValue(navigation, out var expression)) { - if (navigation.IsCollection()) + if (navigation.IsCollection) { expression = new ObjectArrayProjectionExpression(navigation, AccessExpression); } else { expression = new EntityProjectionExpression( - navigation.GetTargetType(), + navigation.TargetEntityType, new ObjectAccessExpression(navigation, AccessExpression)); } diff --git a/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs b/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs index c0488df8eb2..bae05097958 100644 --- a/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs @@ -26,7 +26,7 @@ public class ObjectAccessExpression : Expression, IPrintableExpression, IAccessE /// public ObjectAccessExpression([NotNull] INavigation navigation, [NotNull] Expression accessExpression) { - Name = navigation.GetTargetType().GetContainingPropertyName(); + Name = navigation.TargetEntityType.GetContainingPropertyName(); if (Name == null) { throw new InvalidOperationException( diff --git a/src/EFCore.Cosmos/Query/Internal/ObjectArrayProjectionExpression.cs b/src/EFCore.Cosmos/Query/Internal/ObjectArrayProjectionExpression.cs index b270435f2fa..601b80611eb 100644 --- a/src/EFCore.Cosmos/Query/Internal/ObjectArrayProjectionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/ObjectArrayProjectionExpression.cs @@ -30,7 +30,7 @@ public ObjectArrayProjectionExpression( [NotNull] Expression accessExpression, [CanBeNull] EntityProjectionExpression innerProjection = null) { - var targetType = navigation.GetTargetType(); + var targetType = navigation.TargetEntityType; Type = typeof(IEnumerable<>).MakeGenericType(targetType.ClrType); Name = targetType.GetContainingPropertyName(); diff --git a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs index 5ff9b03edaf..426766649ef 100644 --- a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs +++ b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs @@ -98,7 +98,7 @@ public virtual JObject CreateDocument([NotNull] IUpdateEntry entry, int? ordinal { var fk = embeddedNavigation.ForeignKey; if (!fk.IsOwnership - || embeddedNavigation.IsDependentToPrincipal() + || embeddedNavigation.IsOnDependent || fk.DeclaringEntityType.IsDocumentRoot()) { continue; @@ -177,7 +177,7 @@ public virtual JObject UpdateDocument([NotNull] JObject document, [NotNull] IUpd { var fk = ownedNavigation.ForeignKey; if (!fk.IsOwnership - || ownedNavigation.IsDependentToPrincipal() + || ownedNavigation.IsOnDependent || fk.DeclaringEntityType.IsDocumentRoot()) { continue; diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs index 85cc555c21b..60f71bec2bf 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs @@ -171,7 +171,7 @@ protected virtual void GenerateConstructor( { Check.NotNull(entityType, nameof(entityType)); - var collectionNavigations = entityType.GetNavigations().Where(n => n.IsCollection()).ToList(); + var collectionNavigations = entityType.GetNavigations().Where(n => n.IsCollection).ToList(); if (collectionNavigations.Count > 0) { @@ -182,7 +182,7 @@ protected virtual void GenerateConstructor( { foreach (var navigation in collectionNavigations) { - _sb.AppendLine($"{navigation.Name} = new HashSet<{navigation.GetTargetType().Name}>();"); + _sb.AppendLine($"{navigation.Name} = new HashSet<{navigation.TargetEntityType.Name}>();"); } } @@ -304,8 +304,8 @@ protected virtual void GenerateNavigationProperties( Check.NotNull(entityType, nameof(entityType)); var sortedNavigations = entityType.GetNavigations() - .OrderBy(n => n.IsDependentToPrincipal() ? 0 : 1) - .ThenBy(n => n.IsCollection() ? 1 : 0) + .OrderBy(n => n.IsOnDependent ? 0 : 1) + .ThenBy(n => n.IsCollection ? 1 : 0) .ToList(); if (sortedNavigations.Any()) @@ -319,8 +319,8 @@ protected virtual void GenerateNavigationProperties( GenerateNavigationDataAnnotations(navigation); } - var referencedTypeName = navigation.GetTargetType().Name; - var navigationType = navigation.IsCollection() ? $"ICollection<{referencedTypeName}>" : referencedTypeName; + var referencedTypeName = navigation.TargetEntityType.Name; + var navigationType = navigation.IsCollection ? $"ICollection<{referencedTypeName}>" : referencedTypeName; _sb.AppendLine($"public virtual {navigationType} {navigation.Name} {{ get; set; }}"); } } @@ -334,7 +334,7 @@ private void GenerateNavigationDataAnnotations(INavigation navigation) private void GenerateForeignKeyAttribute(INavigation navigation) { - if (navigation.IsDependentToPrincipal()) + if (navigation.IsOnDependent) { if (navigation.ForeignKey.PrincipalKey.IsPrimaryKey()) { @@ -360,7 +360,7 @@ private void GenerateInversePropertyAttribute(INavigation navigation) { if (navigation.ForeignKey.PrincipalKey.IsPrimaryKey()) { - var inverseNavigation = navigation.FindInverse(); + var inverseNavigation = navigation.Inverse; if (inverseNavigation != null) { diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs index 83f22ee3b33..8f320b11b1b 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs @@ -1022,7 +1022,7 @@ private Expression TryExpand(Expression source, MemberIdentity member) return null; } - var targetEntityType = navigation.GetTargetType(); + var targetEntityType = navigation.TargetEntityType; if (targetEntityType == null || (!targetEntityType.HasDefiningNavigation() && !targetEntityType.IsOwned())) @@ -1031,7 +1031,7 @@ private Expression TryExpand(Expression source, MemberIdentity member) } var foreignKey = navigation.ForeignKey; - if (navigation.IsCollection()) + if (navigation.IsCollection) { var innerShapedQuery = CreateShapedQueryExpression(targetEntityType); var innerQueryExpression = (InMemoryQueryExpression)innerShapedQuery.QueryExpression; @@ -1042,12 +1042,12 @@ private Expression TryExpand(Expression source, MemberIdentity member) .Any(t => t.IsNullableType()); var outerKey = entityShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.Properties : foreignKey.PrincipalKey.Properties, makeNullable); var innerKey = innerShapedQuery.ShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.PrincipalKey.Properties : foreignKey.Properties, makeNullable); @@ -1090,12 +1090,12 @@ ProjectionBindingExpression projectionBindingExpression .Any(t => t.IsNullableType()); var outerKey = entityShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.Properties : foreignKey.PrincipalKey.Properties, makeNullable); var innerKey = innerShapedQuery.ShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.PrincipalKey.Properties : foreignKey.Properties, makeNullable); diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs index 4c0322473d1..3aaa2591fd2 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs @@ -79,7 +79,7 @@ private static void IncludeReference { fixup(includingEntity, relatedEntity); if (inverseNavigation != null - && !inverseNavigation.IsCollection()) + && !inverseNavigation.IsCollection) { SetIsLoadedNoTracking(relatedEntity, inverseNavigation); } @@ -165,15 +165,15 @@ protected override Expression VisitExtension(Expression extensionExpression) { var entityClrType = includeExpression.EntityExpression.Type; var includingClrType = includeExpression.Navigation.DeclaringEntityType.ClrType; - var inverseNavigation = includeExpression.Navigation.FindInverse(); - var relatedEntityClrType = includeExpression.Navigation.GetTargetType().ClrType; + var inverseNavigation = includeExpression.Navigation.Inverse; + var relatedEntityClrType = includeExpression.Navigation.TargetEntityType.ClrType; if (includingClrType != entityClrType && includingClrType.IsAssignableFrom(entityClrType)) { includingClrType = entityClrType; } - if (includeExpression.Navigation.IsCollection()) + if (includeExpression.Navigation.IsCollection) { var collectionShaper = (CollectionShaperExpression)includeExpression.NavigationExpression; return Expression.Call( @@ -240,7 +240,7 @@ private static LambdaExpression GenerateFixup( var relatedEntityParameter = Expression.Parameter(relatedEntityType); var expressions = new List { - navigation.IsCollection() + navigation.IsCollection ? AddToCollectionNavigation(entityParameter, relatedEntityParameter, navigation) : AssignReferenceNavigation(entityParameter, relatedEntityParameter, navigation) }; @@ -248,7 +248,7 @@ private static LambdaExpression GenerateFixup( if (inverseNavigation != null) { expressions.Add( - inverseNavigation.IsCollection() + inverseNavigation.IsCollection ? AddToCollectionNavigation(relatedEntityParameter, entityParameter, inverseNavigation) : AssignReferenceNavigation(relatedEntityParameter, entityParameter, inverseNavigation)); } diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs index 96ceabbf3cc..04e2820db79 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -1120,7 +1120,7 @@ private Expression TryExpand(Expression source, MemberIdentity member) return null; } - var targetEntityType = navigation.GetTargetType(); + var targetEntityType = navigation.TargetEntityType; if (targetEntityType == null || (!targetEntityType.HasDefiningNavigation() && !targetEntityType.IsOwned())) @@ -1129,7 +1129,7 @@ private Expression TryExpand(Expression source, MemberIdentity member) } var foreignKey = navigation.ForeignKey; - if (navigation.IsCollection()) + if (navigation.IsCollection) { var innerShapedQuery = CreateShapedQueryExpression( targetEntityType, _sqlExpressionFactory.Select(targetEntityType)); @@ -1143,12 +1143,12 @@ private Expression TryExpand(Expression source, MemberIdentity member) var correlationPredicateParameter = Expression.Parameter(innerSequenceType); var outerKey = entityShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.Properties : foreignKey.PrincipalKey.Properties, makeNullable); var innerKey = correlationPredicateParameter.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.PrincipalKey.Properties : foreignKey.Properties, makeNullable); @@ -1188,12 +1188,12 @@ private Expression TryExpand(Expression source, MemberIdentity member) .Any(t => t.IsNullableType()); var outerKey = entityShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.Properties : foreignKey.PrincipalKey.Properties, makeNullable); var innerKey = innerShapedQuery.ShaperExpression.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? foreignKey.PrincipalKey.Properties : foreignKey.Properties, makeNullable); diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs index 772a309b370..6bc68a1ae4b 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs @@ -65,7 +65,7 @@ private static void IncludeReference { fixup(includingEntity, relatedEntity); if (inverseNavigation != null - && !inverseNavigation.IsCollection()) + && !inverseNavigation.IsCollection) { SetIsLoadedNoTracking(relatedEntity, inverseNavigation); } @@ -382,12 +382,12 @@ protected override Expression VisitExtension(Expression extensionExpression) if (extensionExpression is IncludeExpression includeExpression) { Check.DebugAssert( - !includeExpression.Navigation.IsCollection(), + !includeExpression.Navigation.IsCollection, "Only reference include should be present in tree"); var entityClrType = includeExpression.EntityExpression.Type; var includingClrType = includeExpression.Navigation.DeclaringEntityType.ClrType; - var inverseNavigation = includeExpression.Navigation.FindInverse(); - var relatedEntityClrType = includeExpression.Navigation.GetTargetType().ClrType; + var inverseNavigation = includeExpression.Navigation.Inverse; + var relatedEntityClrType = includeExpression.Navigation.TargetEntityType.ClrType; if (includingClrType != entityClrType && includingClrType.IsAssignableFrom(entityClrType)) { @@ -475,7 +475,7 @@ protected override Expression VisitExtension(Expression extensionExpression) if (collectionPopulatingExpression.IsInclude) { var entityClrType = collectionShaper.Navigation.DeclaringEntityType.ClrType; - var inverseNavigation = collectionShaper.Navigation.FindInverse(); + var inverseNavigation = collectionShaper.Navigation.Inverse; return Expression.Call( _populateIncludeCollectionMethodInfo.MakeGenericMethod(entityClrType, relatedEntityClrType), @@ -551,7 +551,7 @@ private static LambdaExpression GenerateFixup( var relatedEntityParameter = Expression.Parameter(relatedEntityType); var expressions = new List { - navigation.IsCollection() + navigation.IsCollection ? AddToCollectionNavigation(entityParameter, relatedEntityParameter, navigation) : AssignReferenceNavigation(entityParameter, relatedEntityParameter, navigation) }; @@ -559,7 +559,7 @@ private static LambdaExpression GenerateFixup( if (inverseNavigation != null) { expressions.Add( - inverseNavigation.IsCollection() + inverseNavigation.IsCollection ? AddToCollectionNavigation(relatedEntityParameter, entityParameter, inverseNavigation) : AssignReferenceNavigation(relatedEntityParameter, entityParameter, inverseNavigation)); } diff --git a/src/EFCore/ChangeTracking/CollectionEntry.cs b/src/EFCore/ChangeTracking/CollectionEntry.cs index 1ca913736d3..a4cf7787ac5 100644 --- a/src/EFCore/ChangeTracking/CollectionEntry.cs +++ b/src/EFCore/ChangeTracking/CollectionEntry.cs @@ -57,7 +57,7 @@ private void LocalDetectChanges() var collection = CurrentValue; if (collection != null) { - var targetType = Metadata.GetTargetType(); + var targetType = Metadata.TargetEntityType; var context = InternalEntry.StateManager.Context; var changeDetector = context.ChangeTracker.AutoDetectChangesEnabled && (string)context.Model[ChangeDetector.SkipDetectChangesAnnotation] != "true" @@ -167,6 +167,6 @@ protected virtual InternalEntityEntry GetInternalTargetEntry([NotNull] object en => CurrentValue == null || !((Navigation)Metadata).CollectionAccessor.Contains(InternalEntry.Entity, entity) ? null - : InternalEntry.StateManager.GetOrCreateEntry(entity, Metadata.GetTargetType()); + : InternalEntry.StateManager.GetOrCreateEntry(entity, Metadata.TargetEntityType); } } diff --git a/src/EFCore/ChangeTracking/EntityEntry.cs b/src/EFCore/ChangeTracking/EntityEntry.cs index e7495da61e1..f7d260c5c77 100644 --- a/src/EFCore/ChangeTracking/EntityEntry.cs +++ b/src/EFCore/ChangeTracking/EntityEntry.cs @@ -142,7 +142,7 @@ public virtual MemberEntry Member([NotNull] string propertyName) var navigation = InternalEntry.EntityType.FindNavigation(propertyName); if (navigation != null) { - return navigation.IsCollection() + return navigation.IsCollection ? (MemberEntry)new CollectionEntry(InternalEntry, propertyName) : new ReferenceEntry(InternalEntry, propertyName); } @@ -171,7 +171,7 @@ public virtual NavigationEntry Navigation([NotNull] string propertyName) var navigation = InternalEntry.EntityType.FindNavigation(propertyName); if (navigation != null) { - return navigation.IsCollection() + return navigation.IsCollection ? (NavigationEntry)new CollectionEntry(InternalEntry, propertyName) : new ReferenceEntry(InternalEntry, propertyName); } @@ -194,7 +194,7 @@ public virtual NavigationEntry Navigation([NotNull] string propertyName) /// public virtual IEnumerable Navigations => InternalEntry.EntityType.GetNavigations().Select( - navigation => navigation.IsCollection() + navigation => navigation.IsCollection ? (NavigationEntry)new CollectionEntry(InternalEntry, navigation) : new ReferenceEntry(InternalEntry, navigation)); @@ -239,7 +239,7 @@ public virtual ReferenceEntry Reference([NotNull] string propertyName) /// reference (i.e. non-collection) navigation properties of this entity. /// public virtual IEnumerable References - => InternalEntry.EntityType.GetNavigations().Where(n => !n.IsCollection()) + => InternalEntry.EntityType.GetNavigations().Where(n => !n.IsCollection) .Select(navigation => new ReferenceEntry(InternalEntry, navigation)); /// @@ -263,7 +263,7 @@ public virtual CollectionEntry Collection([NotNull] string propertyName) /// collection navigation properties of this entity. /// public virtual IEnumerable Collections - => InternalEntry.EntityType.GetNavigations().Where(n => n.IsCollection()) + => InternalEntry.EntityType.GetNavigations().Where(n => n.IsCollection) .Select(navigation => new CollectionEntry(InternalEntry, navigation)); /// diff --git a/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs b/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs index 4ff029c0101..04ac3270db9 100644 --- a/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs +++ b/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs @@ -285,7 +285,7 @@ private void DetectNavigationChange(InternalEntityEntry entry, INavigation navig var currentValue = entry[navigation]; var stateManager = entry.StateManager; - if (navigation.IsCollection()) + if (navigation.IsCollection) { var snapshotCollection = (IEnumerable)snapshotValue; var currentCollection = (IEnumerable)currentValue; @@ -328,7 +328,7 @@ private void DetectNavigationChange(InternalEntityEntry entry, INavigation navig } else if (!ReferenceEquals(currentValue, snapshotValue) && (!navigation.ForeignKey.IsOwnership - || !navigation.IsDependentToPrincipal())) + || !navigation.IsOnDependent)) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { diff --git a/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs b/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs index fba415957fc..f36856376e2 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal @@ -43,7 +42,7 @@ public virtual void TraverseGraph( } var internalEntityEntry = node.GetInfrastructure(); - var navigations = ((EntityType)internalEntityEntry.EntityType).GetNavigations(); + var navigations = internalEntityEntry.EntityType.GetNavigations(); var stateManager = internalEntityEntry.StateManager; foreach (var navigation in navigations) @@ -52,8 +51,8 @@ public virtual void TraverseGraph( if (navigationValue != null) { - var targetEntityType = navigation.GetTargetType(); - if (navigation.IsCollection()) + var targetEntityType = navigation.TargetEntityType; + if (navigation.IsCollection) { foreach (var relatedEntity in ((IEnumerable)navigationValue).Cast().ToList()) { @@ -100,8 +99,8 @@ public virtual async Task TraverseGraphAsync( if (navigationValue != null) { - var targetType = navigation.GetTargetType(); - if (navigation.IsCollection()) + var targetType = navigation.TargetEntityType; + if (navigation.IsCollection) { foreach (var relatedEntity in ((IEnumerable)navigationValue).Cast().ToList()) { diff --git a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs index af07c9781da..d053bec6f94 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs @@ -133,7 +133,7 @@ private static void SetReferenceLoaded( { var inboundNavigation = node.InboundNavigation; if (inboundNavigation != null - && !inboundNavigation.IsCollection()) + && !inboundNavigation.IsCollection) { node.SourceEntry.GetInfrastructure().SetIsLoaded(inboundNavigation); } diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs index 53889226c77..6802bb75794 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs @@ -1211,7 +1211,7 @@ private void SetProperty( if (propertyBase is INavigation navigation) { - if (!navigation.IsCollection()) + if (!navigation.IsCollection) { SetIsLoaded(navigation, value != null); } @@ -1623,7 +1623,7 @@ public virtual void HandleINotifyCollectionChanged( [NotNull] object sender, [NotNull] NotifyCollectionChangedEventArgs eventArgs) { - var navigation = EntityType.GetNavigations().FirstOrDefault(n => n.IsCollection() && this[n] == sender); + var navigation = EntityType.GetNavigations().FirstOrDefault(n => n.IsCollection && this[n] == sender); if (navigation != null) { switch (eventArgs.Action) @@ -1665,7 +1665,7 @@ public virtual void HandleINotifyCollectionChanged( public virtual void SetIsLoaded([NotNull] INavigation navigation, bool loaded = true) { if (!loaded - && !navigation.IsCollection() + && !navigation.IsCollection && this[navigation] != null) { throw new InvalidOperationException( @@ -1803,7 +1803,7 @@ public virtual string ToDebugString(StateManagerDebugStringOptions options) builder.AppendLine(); var currentValue = GetCurrentValue(navigation); - var targetType = navigation.GetTargetType(); + var targetType = navigation.TargetEntityType; builder .Append(" ") @@ -1814,7 +1814,7 @@ public virtual string ToDebugString(StateManagerDebugStringOptions options) { builder.Append(""); } - else if (navigation.IsCollection()) + else if (navigation.IsCollection) { builder.Append('['); diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs index 6078c573600..017176d5620 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs @@ -51,7 +51,7 @@ public virtual bool SnapshotAndSubscribe(InternalEntityEntry entry) return false; } - foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection())) + foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection)) { AsINotifyCollectionChanged(entry, navigation, entityType, changeTrackingStrategy).CollectionChanged += entry.HandleINotifyCollectionChanged; @@ -82,7 +82,7 @@ public virtual void Unsubscribe(InternalEntityEntry entry) if (changeTrackingStrategy != ChangeTrackingStrategy.Snapshot) { - foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection())) + foreach (var navigation in entityType.GetNavigations().Where(n => n.IsCollection)) { AsINotifyCollectionChanged(entry, navigation, entityType, changeTrackingStrategy).CollectionChanged -= entry.HandleINotifyCollectionChanged; diff --git a/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs index e673214d14d..2a1e1a5a622 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs @@ -159,7 +159,7 @@ public override bool AddToCollection(INavigation navigation, InternalEntityEntry return base.AddToCollection(navigation, value, forMaterialization); } - if (navigation.GetTargetType().ClrType == null) + if (navigation.TargetEntityType.ClrType == null) { return false; } diff --git a/src/EFCore/ChangeTracking/Internal/InternalShadowEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalShadowEntityEntry.cs index 90837019af3..029bcb4ff61 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalShadowEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalShadowEntityEntry.cs @@ -133,7 +133,7 @@ public override bool CollectionContains(INavigation navigation, InternalEntityEn /// public override bool AddToCollection(INavigation navigation, InternalEntityEntry value, bool forMaterialization) { - if (navigation.GetTargetType().ClrType == null) + if (navigation.TargetEntityType.ClrType == null) { return false; } diff --git a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs index 9b8c8636054..7f7c36b49ba 100644 --- a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs +++ b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs @@ -60,8 +60,8 @@ public virtual void NavigationReferenceChanged(InternalEntityEntry entry, INavig var foreignKey = navigation.ForeignKey; var stateManager = entry.StateManager; - var inverse = navigation.FindInverse(); - var targetEntityType = navigation.GetTargetType(); + var inverse = navigation.Inverse; + var targetEntityType = navigation.TargetEntityType; var oldTargetEntry = oldValue == null ? null : stateManager.TryGetEntry(oldValue, targetEntityType); if (oldTargetEntry?.EntityState == EntityState.Detached) @@ -79,7 +79,7 @@ public virtual void NavigationReferenceChanged(InternalEntityEntry entry, INavig { _inFixup = true; - if (navigation.IsDependentToPrincipal()) + if (navigation.IsOnDependent) { if (newValue != null) { @@ -220,8 +220,8 @@ public virtual void NavigationCollectionChanged( var foreignKey = navigation.ForeignKey; var stateManager = entry.StateManager; - var inverse = navigation.FindInverse(); - var targetEntityType = navigation.GetTargetType(); + var inverse = navigation.Inverse; + var targetEntityType = navigation.TargetEntityType; foreach (var oldValue in removed) { @@ -655,7 +655,7 @@ private void InitialFixup( var navigationValue = entry[principalToDependent]; if (navigationValue != null) { - if (principalToDependent.IsCollection()) + if (principalToDependent.IsCollection) { var dependents = ((IEnumerable)navigationValue).Cast().ToList(); foreach (var dependentEntity in dependents) @@ -676,7 +676,7 @@ private void InitialFixup( } else { - var targetEntityType = principalToDependent.GetTargetType(); + var targetEntityType = principalToDependent.TargetEntityType; var dependentEntry = stateManager.TryGetEntry(navigationValue, targetEntityType); if (dependentEntry == null || dependentEntry.EntityState == EntityState.Detached) @@ -703,7 +703,7 @@ private void InitialFixup( var navigationValue = entry[dependentToPrincipal]; if (navigationValue != null) { - var targetEntityType = dependentToPrincipal.GetTargetType(); + var targetEntityType = dependentToPrincipal.TargetEntityType; var principalEntry = stateManager.TryGetEntry(navigationValue, targetEntityType); if (principalEntry == null || principalEntry.EntityState == EntityState.Detached) @@ -737,9 +737,9 @@ private void DelayedFixup(InternalEntityEntry entry, INavigation navigation, Int { var setModified = referencedEntry.EntityState != EntityState.Unchanged; - if (!navigation.IsDependentToPrincipal()) + if (!navigation.IsOnDependent) { - if (navigation.IsCollection()) + if (navigation.IsCollection) { if (entry.CollectionContains(navigation, referencedEntry)) { @@ -997,7 +997,7 @@ private void SetReferenceOrAddToCollection( InternalEntityEntry value, bool fromQuery) { - if (navigation.IsCollection()) + if (navigation.IsCollection) { AddToCollection(entry, navigation, value, fromQuery); } @@ -1013,7 +1013,7 @@ private void ResetReferenceOrRemoveCollection( InternalEntityEntry value, bool fromQuery) { - if (navigation.IsCollection()) + if (navigation.IsCollection) { RemoveFromCollection(entry, navigation, value); } diff --git a/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs b/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs index d33572288e5..a3a9e957a43 100644 --- a/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs @@ -41,7 +41,7 @@ public void SetValue(IPropertyBase propertyBase, object value) Check.DebugAssert(!IsEmpty, "relationship snapshot is empty"); Check.DebugAssert( - !(propertyBase is INavigation) || !((INavigation)propertyBase).IsCollection(), + !(propertyBase is INavigation) || !((INavigation)propertyBase).IsCollection, $"property {propertyBase} is is not reference navigation"); _values[propertyBase.GetRelationshipIndex()] = SnapshotValue(propertyBase, value); diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs index 45550ba80d3..4abedf7fdbd 100644 --- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs @@ -150,7 +150,7 @@ protected virtual Expression CreateSnapshotExpression( memberAccess = Expression.Convert(memberAccess, propertyBase.ClrType); } - arguments[i] = (propertyBase as INavigation)?.IsCollection() ?? false + arguments[i] = (propertyBase as INavigation)?.IsCollection ?? false ? Expression.Call( null, _snapshotCollectionMethod, diff --git a/src/EFCore/ChangeTracking/NavigationEntry.cs b/src/EFCore/ChangeTracking/NavigationEntry.cs index 41cb9ba714c..46319090410 100644 --- a/src/EFCore/ChangeTracking/NavigationEntry.cs +++ b/src/EFCore/ChangeTracking/NavigationEntry.cs @@ -70,7 +70,7 @@ private static INavigation GetNavigation(InternalEntityEntry internalEntry, stri } if (collection - && !navigation.IsCollection()) + && !navigation.IsCollection) { throw new InvalidOperationException( CoreStrings.CollectionIsReference( @@ -79,7 +79,7 @@ private static INavigation GetNavigation(InternalEntityEntry internalEntry, stri } if (!collection - && navigation.IsCollection()) + && navigation.IsCollection) { throw new InvalidOperationException( CoreStrings.ReferenceIsCollection( @@ -175,7 +175,7 @@ public virtual bool IsLoaded } private IEntityFinder TargetFinder - => InternalEntry.StateManager.CreateEntityFinder(Metadata.GetTargetType()); + => InternalEntry.StateManager.CreateEntityFinder(Metadata.TargetEntityType); /// /// Gets or sets a value indicating whether any of foreign key property values associated @@ -186,7 +186,7 @@ public override bool IsModified { get { - if (Metadata.IsDependentToPrincipal()) + if (Metadata.IsOnDependent) { return AnyFkPropertiesModified(InternalEntry); } @@ -194,13 +194,13 @@ public override bool IsModified var navigationValue = CurrentValue; return navigationValue != null - && (Metadata.IsCollection() + && (Metadata.IsCollection ? ((IEnumerable)navigationValue).OfType().Any(CollectionContainsNewOrChangedRelationships) : AnyFkPropertiesModified(navigationValue)); } set { - if (Metadata.IsDependentToPrincipal()) + if (Metadata.IsOnDependent) { SetFkPropertiesModified(InternalEntry, value); } @@ -209,7 +209,7 @@ public override bool IsModified var navigationValue = CurrentValue; if (navigationValue != null) { - if (Metadata.IsCollection()) + if (Metadata.IsCollection) { foreach (var relatedEntity in (IEnumerable)navigationValue) { @@ -227,7 +227,7 @@ public override bool IsModified private bool CollectionContainsNewOrChangedRelationships(object relatedEntity) { - var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.GetTargetType()); + var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.TargetEntityType); return relatedEntry != null && (relatedEntry.EntityState == EntityState.Added @@ -237,7 +237,7 @@ private bool CollectionContainsNewOrChangedRelationships(object relatedEntity) private bool AnyFkPropertiesModified(object relatedEntity) { - var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.GetTargetType()); + var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.TargetEntityType); return relatedEntry != null && Metadata.ForeignKey.Properties.Any(relatedEntry.IsModified); @@ -245,7 +245,7 @@ private bool AnyFkPropertiesModified(object relatedEntity) private void SetFkPropertiesModified(object relatedEntity, bool modified) { - var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.GetTargetType()); + var relatedEntry = InternalEntry.StateManager.TryGetEntry(relatedEntity, Metadata.TargetEntityType); if (relatedEntry != null) { SetFkPropertiesModified(relatedEntry, modified); diff --git a/src/EFCore/ChangeTracking/ReferenceEntry.cs b/src/EFCore/ChangeTracking/ReferenceEntry.cs index 96002da71d7..cc49d6b88fb 100644 --- a/src/EFCore/ChangeTracking/ReferenceEntry.cs +++ b/src/EFCore/ChangeTracking/ReferenceEntry.cs @@ -49,7 +49,7 @@ public ReferenceEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] INa private void LocalDetectChanges() { - if (!Metadata.IsDependentToPrincipal()) + if (!Metadata.IsOnDependent) { var target = GetTargetEntry(); if (target != null) @@ -87,6 +87,6 @@ public virtual EntityEntry TargetEntry protected virtual InternalEntityEntry GetTargetEntry() => CurrentValue == null ? null - : InternalEntry.StateManager.GetOrCreateEntry(CurrentValue, Metadata.GetTargetType()); + : InternalEntry.StateManager.GetOrCreateEntry(CurrentValue, Metadata.TargetEntityType); } } diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 41633a63be7..b49a18188f2 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -495,7 +495,7 @@ public static void PossibleUnintendedCollectionNavigationNullComparisonWarning( { definition.Log( diagnostics, - $"{navigation.DeclaringEntityType.Name}.{navigation.GetTargetType().Name}"); + $"{navigation.DeclaringEntityType.Name}.{navigation.TargetEntityType.Name}"); } if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) @@ -513,7 +513,7 @@ private static string PossibleUnintendedCollectionNavigationNullComparisonWarnin { var d = (EventDefinition)definition; var p = (NavigationEventData)payload; - return d.GenerateMessage($"{p.Navigation.DeclaringEntityType.Name}.{p.Navigation.GetTargetType().Name}"); + return d.GenerateMessage($"{p.Navigation.DeclaringEntityType.Name}.{p.Navigation.TargetEntityType.Name}"); } /// diff --git a/src/EFCore/Extensions/ConventionNavigationExtensions.cs b/src/EFCore/Extensions/ConventionNavigationExtensions.cs index 331bca87f95..b4087e1723a 100644 --- a/src/EFCore/Extensions/ConventionNavigationExtensions.cs +++ b/src/EFCore/Extensions/ConventionNavigationExtensions.cs @@ -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; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -13,16 +14,6 @@ namespace Microsoft.EntityFrameworkCore /// public static class ConventionNavigationExtensions { - /// - /// Returns the configuration source for the navigation. - /// - /// The navigation property to find configuration source for. - /// The configuration source for the navigation. - public static ConfigurationSource? GetConfigurationSource([NotNull] this IConventionNavigation navigation) - => navigation.IsDependentToPrincipal() - ? navigation.ForeignKey.GetDependentToPrincipalConfigurationSource() - : navigation.ForeignKey.GetPrincipalToDependentConfigurationSource(); - /// /// Gets the navigation property on the other end of the relationship. Returns null if /// there is no navigation property defined on the other end of the relationship. @@ -31,8 +22,9 @@ public static class ConventionNavigationExtensions /// /// The inverse navigation, or null if none is defined. /// + [Obsolete("Use IConventionNavigation.Inverse")] public static IConventionNavigation FindInverse([NotNull] this IConventionNavigation navigation) - => ((Navigation)navigation).FindInverse(); + => navigation.Inverse; /// /// Gets the entity type that a given navigation property will hold an instance of @@ -40,28 +32,8 @@ public static IConventionNavigation FindInverse([NotNull] this IConventionNaviga /// /// The navigation property to find the target entity type of. /// The target entity type. + [Obsolete("Use IConventionNavigation.TargetEntityType")] public static IConventionEntityType GetTargetType([NotNull] this IConventionNavigation navigation) - => ((Navigation)navigation).GetTargetType(); - - /// - /// Sets a value indicating whether this navigation should be eager loaded by default. - /// - /// The navigation property to set whether it should be eager loaded. - /// A value indicating whether this navigation should be eager loaded by default. - /// Indicates whether the configuration was specified using a data annotation. - public static void SetIsEagerLoaded( - [NotNull] this IConventionNavigation navigation, - bool? eagerLoaded, - bool fromDataAnnotation = false) - => navigation.AsNavigation().SetIsEagerLoaded( - eagerLoaded, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); - - /// - /// Returns the configuration source for . - /// - /// The navigation property to find configuration source for. - /// The configuration source for . - public static ConfigurationSource? GetIsEagerLoadedConfigurationSource([NotNull] this IConventionNavigation navigation) - => navigation.FindAnnotation(CoreAnnotationNames.EagerLoaded)?.GetConfigurationSource(); + => navigation.TargetEntityType; } } diff --git a/src/EFCore/Extensions/EntityTypeExtensions.cs b/src/EFCore/Extensions/EntityTypeExtensions.cs index aa6087ac2eb..2cadbc5c1ff 100644 --- a/src/EFCore/Extensions/EntityTypeExtensions.cs +++ b/src/EFCore/Extensions/EntityTypeExtensions.cs @@ -511,7 +511,7 @@ public static INavigation FindDefiningNavigation([NotNull] this IEntityType enti } var definingNavigation = entityType.DefiningEntityType.FindNavigation(entityType.DefiningNavigationName); - return definingNavigation?.GetTargetType() == entityType ? definingNavigation : null; + return definingNavigation?.TargetEntityType == entityType ? definingNavigation : null; } /// diff --git a/src/EFCore/Extensions/MutableNavigationExtensions.cs b/src/EFCore/Extensions/MutableNavigationExtensions.cs index 620ba2a7d74..6d12fb08951 100644 --- a/src/EFCore/Extensions/MutableNavigationExtensions.cs +++ b/src/EFCore/Extensions/MutableNavigationExtensions.cs @@ -1,9 +1,9 @@ // 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; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore @@ -21,8 +21,9 @@ public static class MutableNavigationExtensions /// /// The inverse navigation, or null if none is defined. /// + [Obsolete("Use IMutableNavigation.Inverse")] public static IMutableNavigation FindInverse([NotNull] this IMutableNavigation navigation) - => ((Navigation)navigation).FindInverse(); + => navigation.Inverse; /// /// Gets the entity type that a given navigation property will hold an instance of @@ -30,15 +31,8 @@ public static IMutableNavigation FindInverse([NotNull] this IMutableNavigation n /// /// The navigation property to find the target entity type of. /// The target entity type. + [Obsolete("Use IMutableNavigation.TargetEntityType")] public static IMutableEntityType GetTargetType([NotNull] this IMutableNavigation navigation) - => ((Navigation)navigation).GetTargetType(); - - /// - /// Sets a value indicating whether this navigation should be eager loaded by default. - /// - /// The navigation property to set whether it should be eager loaded for. - /// A value indicating whether this navigation should be eager loaded by default. - public static void SetIsEagerLoaded([NotNull] this IMutableNavigation navigation, bool? eagerLoaded) - => navigation.AsNavigation().SetIsEagerLoaded(eagerLoaded, ConfigurationSource.Explicit); + => navigation.TargetEntityType; } } diff --git a/src/EFCore/Extensions/NavigationExtensions.cs b/src/EFCore/Extensions/NavigationExtensions.cs index eba202e4705..09ee773bc66 100644 --- a/src/EFCore/Extensions/NavigationExtensions.cs +++ b/src/EFCore/Extensions/NavigationExtensions.cs @@ -1,10 +1,10 @@ // 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; using System.Diagnostics; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace @@ -15,15 +15,6 @@ namespace Microsoft.EntityFrameworkCore /// public static class NavigationExtensions { - /// - /// Gets the for this navigation property, which must be a collection - /// navigation. - /// - /// The navigation property. - /// The accessor. - public static IClrCollectionAccessor GetCollectionAccessor([NotNull] this INavigation navigation) - => navigation.AsNavigation().CollectionAccessor; - /// /// Gets a value indicating whether the given navigation property is the navigation property on the dependent entity /// type that points to the principal entity. @@ -34,8 +25,9 @@ public static IClrCollectionAccessor GetCollectionAccessor([NotNull] this INavig /// type that points to the principal entity, otherwise false. /// [DebuggerStepThrough] + [Obsolete("Use INavigation.IsOnDependent")] public static bool IsDependentToPrincipal([NotNull] this INavigation navigation) - => Check.NotNull(navigation, nameof(navigation)).ForeignKey.DependentToPrincipal == navigation; + => Check.NotNull(navigation, nameof(navigation)).IsOnDependent; /// /// Gets a value indicating whether the given navigation property is a collection property. @@ -45,12 +37,9 @@ public static bool IsDependentToPrincipal([NotNull] this INavigation navigation) /// True if this is a collection property, false if it is a reference property. /// [DebuggerStepThrough] + [Obsolete("Use INavigation.IsCollection")] public static bool IsCollection([NotNull] this INavigation navigation) - { - Check.NotNull(navigation, nameof(navigation)); - - return !navigation.IsDependentToPrincipal() && !navigation.ForeignKey.IsUnique; - } + => Check.NotNull(navigation, nameof(navigation)).IsCollection; /// /// Gets the navigation property on the other end of the relationship. Returns null if @@ -61,8 +50,9 @@ public static bool IsCollection([NotNull] this INavigation navigation) /// The inverse navigation, or null if none is defined. /// [DebuggerStepThrough] + [Obsolete("Use INavigation.Inverse")] public static INavigation FindInverse([NotNull] this INavigation navigation) - => ((Navigation)Check.NotNull(navigation, nameof(navigation))).FindInverse(); + => Check.NotNull(navigation, nameof(navigation)).Inverse; /// /// Gets the entity type that a given navigation property will hold an instance of @@ -71,19 +61,17 @@ public static INavigation FindInverse([NotNull] this INavigation navigation) /// The navigation property to find the target entity type of. /// The target entity type. [DebuggerStepThrough] + [Obsolete("Use INavigation.TargetEntityType")] public static IEntityType GetTargetType([NotNull] this INavigation navigation) - => (Check.NotNull(navigation, nameof(navigation)) as Navigation)?.GetTargetType(); + => Check.NotNull(navigation, nameof(navigation)).TargetEntityType; /// /// Gets a value indicating whether this navigation should be eager loaded by default. /// /// The navigation property to find whether it should be eager loaded. /// A value indicating whether this navigation should be eager loaded by default. + [Obsolete("Use INavigation.IsEagerLoaded")] public static bool IsEagerLoaded([NotNull] this INavigation navigation) - { - Check.NotNull(navigation, nameof(navigation)); - - return (bool?)navigation[CoreAnnotationNames.EagerLoaded] ?? false; - } + => Check.NotNull(navigation, nameof(navigation)).IsEagerLoaded; } } diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs index 1edeaeb53f9..1d89c4eb20d 100644 --- a/src/EFCore/Infrastructure/ModelValidator.cs +++ b/src/EFCore/Infrastructure/ModelValidator.cs @@ -1010,8 +1010,8 @@ protected virtual void ValidateData([NotNull] IModel model, [NotNull] IDiagnosti foreach (var navigation in entityType.GetNavigations()) { if (seedDatum.TryGetValue(navigation.Name, out var value) - && ((navigation.IsCollection() && value is IEnumerable collection && collection.Any()) - || (!navigation.IsCollection() && value != null))) + && ((navigation.IsCollection && value is IEnumerable collection && collection.Any()) + || (!navigation.IsCollection && value != null))) { if (sensitiveDataLogged) { @@ -1020,7 +1020,7 @@ protected virtual void ValidateData([NotNull] IModel model, [NotNull] IDiagnosti entityType.DisplayName(), string.Join(", ", key.Properties.Select((p, i) => p.Name + ":" + keyValues[i])), navigation.Name, - navigation.GetTargetType().DisplayName(), + navigation.TargetEntityType.DisplayName(), navigation.ForeignKey.Properties.Format())); } @@ -1028,7 +1028,7 @@ protected virtual void ValidateData([NotNull] IModel model, [NotNull] IDiagnosti CoreStrings.SeedDatumNavigation( entityType.DisplayName(), navigation.Name, - navigation.GetTargetType().DisplayName(), + navigation.TargetEntityType.DisplayName(), navigation.ForeignKey.Properties.Format())); } } diff --git a/src/EFCore/Internal/EntityFinder.cs b/src/EFCore/Internal/EntityFinder.cs index 8f9f4a4a5d0..31c3a515002 100644 --- a/src/EFCore/Internal/EntityFinder.cs +++ b/src/EFCore/Internal/EntityFinder.cs @@ -246,7 +246,7 @@ IQueryable IEntityFinder.Query(INavigation navigation, InternalEntityEntry entry private static object[] GetLoadValues(INavigation navigation, InternalEntityEntry entry) { - var properties = navigation.IsDependentToPrincipal() + var properties = navigation.IsOnDependent ? navigation.ForeignKey.Properties : navigation.ForeignKey.PrincipalKey.Properties; @@ -267,7 +267,7 @@ private static object[] GetLoadValues(INavigation navigation, InternalEntityEntr } private static IReadOnlyList GetLoadProperties(INavigation navigation) - => navigation.IsDependentToPrincipal() + => navigation.IsOnDependent ? navigation.ForeignKey.PrincipalKey.Properties : navigation.ForeignKey.Properties; diff --git a/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs index 46e7982e942..716a0da0ad6 100644 --- a/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs +++ b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs @@ -77,7 +77,7 @@ public virtual void ProcessNavigationAdded( var field = GetFieldToSet(navigation); if (field != null) { - relationshipBuilder.HasField(field, navigation.IsDependentToPrincipal()); + relationshipBuilder.HasField(field, navigation.IsOnDependent); } } diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs index 7159ff89fba..a0435bf6d47 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs @@ -121,7 +121,7 @@ var fkPropertiesOnDependentToPrincipal } else { - if (foreignKey.PrincipalToDependent.IsCollection()) + if (foreignKey.PrincipalToDependent.IsCollection) { context.StopProcessing(); return; @@ -401,7 +401,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { foreach (var declaredNavigation in entityType.GetDeclaredNavigations()) { - if (declaredNavigation.IsCollection()) + if (declaredNavigation.IsCollection) { var foreignKey = declaredNavigation.ForeignKey; var fkPropertyOnPrincipal diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs index 56426310d64..61de6584fed 100644 --- a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs @@ -148,7 +148,7 @@ private IConventionRelationshipBuilder DiscoverProperties( || foreignKey.IsOwnership || foreignKey.DeclaringEntityType.IsKeyless || (!foreignKey.IsUnique && !ConfigurationSource.Convention.Overrides(foreignKey.GetIsUniqueConfigurationSource())) - || foreignKey.PrincipalToDependent?.IsCollection() == true + || foreignKey.PrincipalToDependent?.IsCollection == true || foreignKey.DeclaringEntityType.FindOwnership() != null) { relationshipBuilder = relationshipBuilder.HasEntityTypes( @@ -473,7 +473,7 @@ public virtual void ProcessNavigationAdded( IConventionContext context) { var newRelationshipBuilder = DiscoverProperties(relationshipBuilder, context); - context.StopProcessingIfChanged(newRelationshipBuilder?.Metadata.GetNavigation(navigation.IsDependentToPrincipal())); + context.StopProcessingIfChanged(newRelationshipBuilder?.Metadata.GetNavigation(navigation.IsOnDependent)); } /// diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs index 2e9a46b5cec..fe1e27b2097 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs +++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs @@ -581,7 +581,7 @@ public override IConventionNavigation OnNavigationAdded( IConventionRelationshipBuilder relationshipBuilder, IConventionNavigation navigation) { if (relationshipBuilder.Metadata.Builder == null - || relationshipBuilder.Metadata.GetNavigation(navigation.IsDependentToPrincipal()) != navigation) + || relationshipBuilder.Metadata.GetNavigation(navigation.IsOnDependent) != navigation) { return null; } @@ -599,7 +599,7 @@ public override IConventionNavigation OnNavigationAdded( } } - if (relationshipBuilder.Metadata.GetNavigation(navigation.IsDependentToPrincipal()) != navigation) + if (relationshipBuilder.Metadata.GetNavigation(navigation.IsOnDependent) != navigation) { return null; } @@ -615,7 +615,7 @@ public override IConventionAnnotation OnNavigationAnnotationChanged( IConventionAnnotation oldAnnotation) { if (relationshipBuilder.Metadata.Builder == null - || relationshipBuilder.Metadata.GetNavigation(navigation.IsDependentToPrincipal()) != navigation) + || relationshipBuilder.Metadata.GetNavigation(navigation.IsOnDependent) != navigation) { return null; } diff --git a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs index 9c136ef41ea..ca95d396d22 100644 --- a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs @@ -137,7 +137,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( if (ambiguousInverse != null) { - var existingInverse = targetEntityTypeBuilder.Metadata.FindNavigation(inverseNavigationPropertyInfo)?.FindInverse(); + var existingInverse = targetEntityTypeBuilder.Metadata.FindNavigation(inverseNavigationPropertyInfo)?.Inverse; var existingInverseType = existingInverse?.DeclaringEntityType; if (existingInverse != null && IsAmbiguousInverse( @@ -149,7 +149,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( { fk.Builder.HasNavigation( (string)null, - existingInverse.IsDependentToPrincipal(), + existingInverse.IsOnDependent, fromDataAnnotation: true); } } @@ -163,7 +163,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( { fk.Builder.HasNavigation( (string)null, - existingNavigation.IsDependentToPrincipal(), + existingNavigation.IsOnDependent, fromDataAnnotation: true); } } @@ -178,7 +178,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( { fk.Builder.HasNavigation( (string)null, - existingAmbiguousNavigation.IsDependentToPrincipal(), + existingAmbiguousNavigation.IsOnDependent, fromDataAnnotation: true); } } @@ -280,7 +280,7 @@ public override void ProcessNavigationAdded( var newRelationship = ConfigureInverseNavigation( navigation.DeclaringEntityType.Builder, navigation.GetIdentifyingMemberInfo(), - navigation.GetTargetType().Builder, + navigation.TargetEntityType.Builder, attribute); if (newRelationship != relationshipBuilder) { @@ -290,7 +290,7 @@ public override void ProcessNavigationAdded( return; } - var newNavigation = navigation.IsDependentToPrincipal() + var newNavigation = navigation.IsOnDependent ? newRelationship.Metadata.DependentToPrincipal : newRelationship.Metadata.PrincipalToDependent; diff --git a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs index 13f99ab7f70..4e02cddc036 100644 --- a/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs @@ -42,14 +42,14 @@ public virtual void ProcessNavigationAdded( var modelBuilder = relationshipBuilder.ModelBuilder; if (!IsNonNullable(modelBuilder, navigation) - || navigation.IsCollection()) + || navigation.IsCollection) { return; } - if (!navigation.IsDependentToPrincipal()) + if (!navigation.IsOnDependent) { - var inverse = navigation.FindInverse(); + var inverse = navigation.Inverse; if (inverse != null) { if (IsNonNullable(modelBuilder, inverse)) diff --git a/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs index 90cd8567492..caf81533d12 100644 --- a/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs @@ -241,7 +241,7 @@ private static IReadOnlyList RemoveIncompatibleWithExisti var existingNavigation = entityType.FindNavigation(navigationProperty.GetSimpleMemberName()); if (existingNavigation != null && (existingNavigation.DeclaringEntityType != entityType - || existingNavigation.GetTargetType() != targetEntityType)) + || existingNavigation.TargetEntityType != targetEntityType)) { relationshipCandidate.NavigationProperties.Remove(navigationProperty); continue; @@ -378,7 +378,7 @@ private static bool IsCompatibleInverse( return false; } - var otherEntityType = existingInverse.GetTargetType(); + var otherEntityType = existingInverse.TargetEntityType; if (!entityType.ClrType .IsAssignableFrom(otherEntityType.ClrType)) { @@ -395,7 +395,7 @@ private static bool CanMergeWith( var fk = existingNavigation.ForeignKey; return (fk.IsSelfReferencing() || fk.GetRelatedEntityType(existingNavigation.DeclaringEntityType) == inverseEntityTypeBuilder.Metadata) - && fk.Builder.CanSetNavigation(inverse, !existingNavigation.IsDependentToPrincipal()); + && fk.Builder.CanSetNavigation(inverse, !existingNavigation.IsOnDependent); } private static IReadOnlyList RemoveInheritedInverseNavigations( @@ -478,7 +478,7 @@ private static IReadOnlyList RemoveSingleSidedBaseNavigat foreach (var navigation in relationshipCandidate.NavigationProperties.ToList()) { if (entityTypeBuilder.Metadata.FindDerivedNavigations(navigation.GetSimpleMemberName()) - .Any(n => n.FindInverse() != null)) + .Any(n => n.Inverse != null)) { relationshipCandidate.NavigationProperties.Remove(navigation); } @@ -575,11 +575,9 @@ private void CreateRelationships( var existingNavigation = entityType.FindDeclaredNavigation(navigationProperty.GetSimpleMemberName()); if (existingNavigation != null && existingNavigation.ForeignKey.DeclaringEntityType.Builder - .HasNoRelationship(existingNavigation.ForeignKey) - == null + .HasNoRelationship(existingNavigation.ForeignKey) == null && existingNavigation.ForeignKey.Builder.HasNavigation( - (string)null, existingNavigation.IsDependentToPrincipal()) - == null) + (string)null, existingNavigation.IsOnDependent) == null) { // Navigations of higher configuration source are not ambiguous relationshipCandidate.NavigationProperties.Remove(navigationProperty); @@ -591,11 +589,9 @@ private void CreateRelationships( var existingInverse = targetEntityType.FindDeclaredNavigation(inverseProperty.GetSimpleMemberName()); if (existingInverse != null && existingInverse.ForeignKey.DeclaringEntityType.Builder - .HasNoRelationship(existingInverse.ForeignKey) - == null + .HasNoRelationship(existingInverse.ForeignKey) == null && existingInverse.ForeignKey.Builder.HasNavigation( - (string)null, existingInverse.IsDependentToPrincipal()) - == null) + (string)null, existingInverse.IsOnDependent) == null) { // Navigations of higher configuration source are not ambiguous relationshipCandidate.InverseProperties.Remove(inverseProperty); @@ -935,9 +931,10 @@ public virtual void ProcessNavigationAdded( { foreach (var entityType in navigation.DeclaringEntityType.GetDerivedTypesInclusive()) { + var targetEntityType = navigation.TargetEntityType; // Only run the convention if an ambiguity might have been removed - var ambiguityRemoved = RemoveAmbiguous(entityType, navigation.GetTargetType().ClrType); - var targetAmbiguityRemoved = RemoveAmbiguous(navigation.GetTargetType(), entityType.ClrType); + var ambiguityRemoved = RemoveAmbiguous(entityType, targetEntityType.ClrType); + var targetAmbiguityRemoved = RemoveAmbiguous(targetEntityType, entityType.ClrType); if (ambiguityRemoved) { @@ -946,7 +943,7 @@ public virtual void ProcessNavigationAdded( if (targetAmbiguityRemoved) { - DiscoverRelationships(navigation.GetTargetType().Builder, context); + DiscoverRelationships(targetEntityType.Builder, context); } } diff --git a/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs index 936b4da70a2..78ae911c623 100644 --- a/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs @@ -43,15 +43,15 @@ public override void ProcessNavigationAdded( Check.NotNull(navigation, nameof(navigation)); Check.NotNull(attribute, nameof(attribute)); - if (navigation.IsCollection()) + if (navigation.IsCollection) { Dependencies.Logger.RequiredAttributeOnCollection(navigation.ForeignKey.DependentToPrincipal); return; } - if (!navigation.IsDependentToPrincipal()) + if (!navigation.IsOnDependent) { - var inverse = navigation.FindInverse(); + var inverse = navigation.Inverse; if (inverse != null) { var attributes = GetAttributes(inverse.DeclaringEntityType, inverse); diff --git a/src/EFCore/Metadata/IConventionEntityType.cs b/src/EFCore/Metadata/IConventionEntityType.cs index 03a3cdbb145..aed3986f220 100644 --- a/src/EFCore/Metadata/IConventionEntityType.cs +++ b/src/EFCore/Metadata/IConventionEntityType.cs @@ -183,8 +183,8 @@ IConventionForeignKey AddForeignKey( /// The entity type that the skip navigation property will hold an instance(s) of. /// The foreign key to the association type. /// Whether the navigation property is a collection property. - /// - /// Whether the navigation property is defined on the principal side of the underlying foreign key. + /// + /// Whether the navigation property is defined on the dependent side of the underlying foreign key. /// /// Indicates whether the configuration was specified using a data annotation. /// The newly created skip navigation property. @@ -194,7 +194,7 @@ IConventionSkipNavigation AddSkipNavigation( [NotNull] IConventionEntityType targetEntityType, [CanBeNull] IConventionForeignKey foreignKey, bool collection, - bool onPrincipal, + bool onDependent, bool fromDataAnnotation = false); /// diff --git a/src/EFCore/Metadata/IConventionNavigation.cs b/src/EFCore/Metadata/IConventionNavigation.cs index b666ba8f88e..45aa9611b55 100644 --- a/src/EFCore/Metadata/IConventionNavigation.cs +++ b/src/EFCore/Metadata/IConventionNavigation.cs @@ -1,6 +1,10 @@ // 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.Diagnostics; +using System.Reflection; +using JetBrains.Annotations; + namespace Microsoft.EntityFrameworkCore.Metadata { /// @@ -12,16 +16,55 @@ namespace Microsoft.EntityFrameworkCore.Metadata /// Once the model is built, represents a read-only view of the same metadata. /// /// - public interface IConventionNavigation : INavigation, IConventionPropertyBase + public interface IConventionNavigation : INavigation, IConventionNavigationBase { /// - /// Gets the type that this navigation property belongs to. + /// Returns the configuration source for this navigation property. /// - new IConventionEntityType DeclaringEntityType { get; } + /// The configuration source. + ConfigurationSource IConventionNavigationBase.GetConfigurationSource() + => (ConfigurationSource)(IsOnDependent + ? ForeignKey.GetDependentToPrincipalConfigurationSource() + : ForeignKey.GetPrincipalToDependentConfigurationSource()); /// /// Gets the foreign key that defines the relationship this navigation property will navigate. /// - new IConventionForeignKey ForeignKey { get; } + new IConventionForeignKey ForeignKey + { + [DebuggerStepThrough] + get => (IConventionForeignKey)((INavigation)this).ForeignKey; + } + + /// + /// Gets the inverse navigation. + /// + new IConventionNavigation Inverse + { + [DebuggerStepThrough] + get => (IConventionNavigation)((INavigation)this).Inverse; + } + + /// + /// Sets the inverse navigation. + /// + /// + /// The name of the inverse navigation property. Passing null will result in there being + /// no inverse navigation property defined. + /// + /// Indicates whether the configuration was specified using a data annotation. + [DebuggerStepThrough] + IConventionNavigation SetInverse([CanBeNull] string inverseName, bool fromDataAnnotation = false); + + /// + /// Sets the inverse navigation. + /// + /// + /// The name of the inverse navigation property. Passing null will result in there being + /// no inverse navigation property defined. + /// + /// Indicates whether the configuration was specified using a data annotation. + [DebuggerStepThrough] + IConventionNavigation SetInverse([CanBeNull] MemberInfo inverse, bool fromDataAnnotation = false); } } diff --git a/src/EFCore/Metadata/IConventionNavigationBase.cs b/src/EFCore/Metadata/IConventionNavigationBase.cs new file mode 100644 index 00000000000..edc680ee2e5 --- /dev/null +++ b/src/EFCore/Metadata/IConventionNavigationBase.cs @@ -0,0 +1,55 @@ +// 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 Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata +{ + /// + /// + /// Represents a navigation property which can be used to navigate a relationship. + /// + /// + /// This interface is used during model creation and allows the metadata to be modified. + /// Once the model is built, represents a read-only view of the same metadata. + /// + /// + public interface IConventionNavigationBase : INavigationBase, IConventionPropertyBase + { + /// + /// Gets the type that this navigation property belongs to. + /// + new IConventionEntityType DeclaringEntityType => (IConventionEntityType)((INavigationBase)this).DeclaringEntityType; + + /// + /// Gets the entity type that this navigation property will hold an instance(s) of. + /// + new IConventionEntityType TargetEntityType => (IConventionEntityType)((INavigationBase)this).TargetEntityType; + + /// + /// Returns the configuration source for this navigation property. + /// + /// The configuration source. + ConfigurationSource GetConfigurationSource(); + + /// + /// Gets the inverse navigation. + /// + new IConventionNavigationBase Inverse => (IConventionNavigationBase)((INavigationBase)this).Inverse; + + /// + /// Sets a value indicating whether this navigation should be eager loaded by default. + /// + /// A value indicating whether this navigation should be eager loaded by default. + /// Indicates whether the configuration was specified using a data annotation. + void SetIsEagerLoaded(bool? eagerLoaded, bool fromDataAnnotation = false) + => this.SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, fromDataAnnotation); + + /// + /// Returns the configuration source for . + /// + /// The configuration source for . + ConfigurationSource? GetIsEagerLoadedConfigurationSource() + => FindAnnotation(CoreAnnotationNames.EagerLoaded)?.GetConfigurationSource(); + } +} diff --git a/src/EFCore/Metadata/IConventionSkipNavigation.cs b/src/EFCore/Metadata/IConventionSkipNavigation.cs index a4b8d33a728..187ace2102c 100644 --- a/src/EFCore/Metadata/IConventionSkipNavigation.cs +++ b/src/EFCore/Metadata/IConventionSkipNavigation.cs @@ -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.Diagnostics; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -16,38 +17,30 @@ namespace Microsoft.EntityFrameworkCore.Metadata /// Once the model is built, represents a read-only view of the same metadata. /// /// - public interface IConventionSkipNavigation : ISkipNavigation, IConventionPropertyBase + public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigationBase { /// /// Gets the builder that can be used to configure this property. /// IConventionSkipNavigationBuilder Builder { get; } - /// - /// Gets the type that this navigation property belongs to. - /// - new IConventionEntityType DeclaringEntityType => (IConventionEntityType)((ISkipNavigation)this).DeclaringEntityType; - - /// - /// Gets the entity type that this navigation property will hold an instance(s) of. - /// - new IConventionEntityType TargetEntityType => (IConventionEntityType)((ISkipNavigation)this).TargetEntityType; - /// /// Gets the association type used by the foreign key. /// - new IConventionEntityType AssociationEntityType => (IConventionEntityType)((ISkipNavigation)this).AssociationEntityType; - - /// - /// Returns the configuration source for this property. - /// - /// The configuration source. - ConfigurationSource GetConfigurationSource(); + new IConventionEntityType AssociationEntityType + { + [DebuggerStepThrough] + get => (IConventionEntityType)((ISkipNavigation)this).AssociationEntityType; + } /// /// Gets the foreign key to the association type. /// - new IConventionForeignKey ForeignKey => (IConventionForeignKey)((ISkipNavigation)this).ForeignKey; + new IConventionForeignKey ForeignKey + { + [DebuggerStepThrough] + get => (IConventionForeignKey)((ISkipNavigation)this).ForeignKey; + } /// /// Sets the foreign key. @@ -67,7 +60,11 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionPropert /// /// Gets the inverse skip navigation. /// - new IConventionSkipNavigation Inverse => (IConventionSkipNavigation)((ISkipNavigation)this).Inverse; + new IConventionSkipNavigation Inverse + { + [DebuggerStepThrough] + get => (IConventionSkipNavigation)((ISkipNavigation)this).Inverse; + } /// /// Sets the inverse skip navigation. @@ -76,6 +73,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionPropert /// The inverse skip navigation. Passing null will result in there being no inverse navigation property defined. /// /// Indicates whether the configuration was specified using a data annotation. + [DebuggerStepThrough] IConventionSkipNavigation SetInverse([CanBeNull] IConventionSkipNavigation inverse, bool fromDataAnnotation = false); /// diff --git a/src/EFCore/Metadata/IForeignKey.cs b/src/EFCore/Metadata/IForeignKey.cs index 6ecac7cf913..32b8745247d 100644 --- a/src/EFCore/Metadata/IForeignKey.cs +++ b/src/EFCore/Metadata/IForeignKey.cs @@ -75,7 +75,7 @@ public interface IForeignKey : IAnnotatable /// /// The skip navigations using this foreign key. IEnumerable GetReferencingSkipNavigations() - => PrincipalEntityType.GetSkipNavigations().Where(n => n.IsOnPrincipal && n.ForeignKey == this) - .Concat(DeclaringEntityType.GetSkipNavigations().Where(n => !n.IsOnPrincipal && n.ForeignKey == this)); + => PrincipalEntityType.GetSkipNavigations().Where(n => !n.IsOnDependent && n.ForeignKey == this) + .Concat(DeclaringEntityType.GetSkipNavigations().Where(n => n.IsOnDependent && n.ForeignKey == this)); } } diff --git a/src/EFCore/Metadata/IMutableEntityType.cs b/src/EFCore/Metadata/IMutableEntityType.cs index 46a01964ba6..02809aadd37 100644 --- a/src/EFCore/Metadata/IMutableEntityType.cs +++ b/src/EFCore/Metadata/IMutableEntityType.cs @@ -141,8 +141,8 @@ IMutableForeignKey AddForeignKey( /// The entity type that the skip navigation property will hold an instance(s) of. /// The foreign key to the association type. /// Whether the navigation property is a collection property. - /// - /// Whether the navigation property is defined on the principal side of the underlying foreign key. + /// + /// Whether the navigation property is defined on the dependent side of the underlying foreign key. /// /// The newly created skip navigation property. IMutableSkipNavigation AddSkipNavigation( @@ -151,7 +151,7 @@ IMutableSkipNavigation AddSkipNavigation( [NotNull] IMutableEntityType targetEntityType, [CanBeNull] IMutableForeignKey foreignKey, bool collection, - bool onPrincipal); + bool onDependent); /// /// Gets a skip navigation property on this entity type. Returns null if no navigation property is found. diff --git a/src/EFCore/Metadata/IMutableNavigation.cs b/src/EFCore/Metadata/IMutableNavigation.cs index cbd610e626b..5b4beb1c36a 100644 --- a/src/EFCore/Metadata/IMutableNavigation.cs +++ b/src/EFCore/Metadata/IMutableNavigation.cs @@ -1,6 +1,10 @@ // 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.Diagnostics; +using System.Reflection; +using JetBrains.Annotations; + namespace Microsoft.EntityFrameworkCore.Metadata { /// @@ -12,16 +16,42 @@ namespace Microsoft.EntityFrameworkCore.Metadata /// Once the model is built, represents a read-only view of the same metadata. /// /// - public interface IMutableNavigation : INavigation, IMutablePropertyBase + public interface IMutableNavigation : INavigation, IMutableNavigationBase { /// - /// Gets the type that this navigation property belongs to. + /// Gets the foreign key that defines the relationship this navigation property will navigate. /// - new IMutableEntityType DeclaringEntityType { get; } + new IMutableForeignKey ForeignKey + { + [DebuggerStepThrough] + get => (IMutableForeignKey)((INavigation)this).ForeignKey; + } /// - /// Gets the foreign key that defines the relationship this navigation property will navigate. + /// Gets the inverse navigation. + /// + new IMutableNavigation Inverse + { + [DebuggerStepThrough] + get => (IMutableNavigation)((INavigation)this).Inverse; + } + + /// + /// Sets the inverse navigation. + /// + /// + /// The name of the inverse navigation property. Passing null will result in there being + /// no inverse navigation property defined. + /// + IMutableNavigation SetInverse([CanBeNull] string inverseName); + + /// + /// Sets the inverse navigation. /// - new IMutableForeignKey ForeignKey { get; } + /// + /// The inverse navigation property. Passing null will result in there being + /// no inverse navigation property defined. + /// + IMutableNavigation SetInverse([CanBeNull] MemberInfo inverse); } } diff --git a/src/EFCore/Metadata/IMutableNavigationBase.cs b/src/EFCore/Metadata/IMutableNavigationBase.cs new file mode 100644 index 00000000000..34682fcf962 --- /dev/null +++ b/src/EFCore/Metadata/IMutableNavigationBase.cs @@ -0,0 +1,54 @@ +// 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.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata +{ + /// + /// + /// Represents a navigation property which can be used to navigate a relationship. + /// + /// + /// This interface is used during model creation and allows the metadata to be modified. + /// Once the model is built, represents a read-only view of the same metadata. + /// + /// + public interface IMutableNavigationBase : INavigationBase, IMutablePropertyBase + { + /// + /// Gets the type that this navigation property belongs to. + /// + new IMutableEntityType DeclaringEntityType + { + [DebuggerStepThrough] + get => (IMutableEntityType)((INavigationBase)this).DeclaringEntityType; + } + + /// + /// Gets the entity type that this navigation property will hold an instance(s) of. + /// + new IMutableEntityType TargetEntityType + { + [DebuggerStepThrough] + get => (IMutableEntityType)((INavigationBase)this).TargetEntityType; + } + + /// + /// Gets the inverse skip navigation. + /// + new IMutableNavigationBase Inverse + { + [DebuggerStepThrough] + get => (IMutableNavigationBase)((INavigationBase)this).Inverse; + } + + /// + /// Sets a value indicating whether this navigation should be eager loaded by default. + /// + /// A value indicating whether this navigation should be eager loaded by default. + void SetIsEagerLoaded(bool? eagerLoaded) + => this.SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded); + } +} diff --git a/src/EFCore/Metadata/IMutableSkipNavigation.cs b/src/EFCore/Metadata/IMutableSkipNavigation.cs index 5b4d8572e5e..ac29cdee8c6 100644 --- a/src/EFCore/Metadata/IMutableSkipNavigation.cs +++ b/src/EFCore/Metadata/IMutableSkipNavigation.cs @@ -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.Diagnostics; using JetBrains.Annotations; namespace Microsoft.EntityFrameworkCore.Metadata @@ -15,27 +16,25 @@ namespace Microsoft.EntityFrameworkCore.Metadata /// Once the model is built, represents a read-only view of the same metadata. /// /// - public interface IMutableSkipNavigation : ISkipNavigation, IMutablePropertyBase + public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBase { - /// - /// Gets the type that this navigation property belongs to. - /// - new IMutableEntityType DeclaringEntityType => (IMutableEntityType)((ISkipNavigation)this).DeclaringEntityType; - - /// - /// Gets the entity type that this navigation property will hold an instance(s) of. - /// - new IMutableEntityType TargetEntityType => (IMutableEntityType)((ISkipNavigation)this).TargetEntityType; - /// /// Gets the association type used by the foreign key. /// - new IMutableEntityType AssociationEntityType => (IMutableEntityType)((ISkipNavigation)this).AssociationEntityType; + new IMutableEntityType AssociationEntityType + { + [DebuggerStepThrough] + get => (IMutableEntityType)((ISkipNavigation)this).AssociationEntityType; + } /// /// Gets the foreign key to the association type. /// - new IMutableForeignKey ForeignKey => (IMutableForeignKey)((ISkipNavigation)this).ForeignKey; + new IMutableForeignKey ForeignKey + { + [DebuggerStepThrough] + get => (IMutableForeignKey)((ISkipNavigation)this).ForeignKey; + } /// /// Sets the foreign key. @@ -48,7 +47,11 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutablePropertyBase /// /// Gets the inverse skip navigation. /// - new IMutableSkipNavigation Inverse => (IMutableSkipNavigation)((ISkipNavigation)this).Inverse; + new IMutableSkipNavigation Inverse + { + [DebuggerStepThrough] + get => (IMutableSkipNavigation)((ISkipNavigation)this).Inverse; + } /// /// Sets the inverse skip navigation. @@ -56,6 +59,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutablePropertyBase /// /// The inverse skip navigation. Passing null will result in there being no inverse navigation property defined. /// - IConventionSkipNavigation SetInverse([CanBeNull] IMutableSkipNavigation inverse); + [DebuggerStepThrough] + IMutableSkipNavigation SetInverse([CanBeNull] IMutableSkipNavigation inverse); } } diff --git a/src/EFCore/Metadata/INavigation.cs b/src/EFCore/Metadata/INavigation.cs index 685e9f356d0..77ff126e06e 100644 --- a/src/EFCore/Metadata/INavigation.cs +++ b/src/EFCore/Metadata/INavigation.cs @@ -1,21 +1,81 @@ // 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.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + namespace Microsoft.EntityFrameworkCore.Metadata { /// /// Represents a navigation property which can be used to navigate a relationship. /// - public interface INavigation : IPropertyBase + public interface INavigation : INavigationBase { /// /// Gets the entity type that this navigation property belongs to. /// - IEntityType DeclaringEntityType { get; } + IEntityType INavigationBase.DeclaringEntityType + { + [DebuggerStepThrough] + get => IsOnDependent ? ForeignKey.DeclaringEntityType : ForeignKey.PrincipalEntityType; + } + + /// + /// Gets the entity type that this navigation property will hold an instance(s) of. + /// + IEntityType INavigationBase.TargetEntityType + { + [DebuggerStepThrough] + get => IsOnDependent ? ForeignKey.PrincipalEntityType : ForeignKey.DeclaringEntityType; + } + + /// + /// Gets the inverse navigation. + /// + new INavigation Inverse + { + [DebuggerStepThrough] + get => IsOnDependent ? ForeignKey.PrincipalToDependent : ForeignKey.DependentToPrincipal; + } + + /// + /// Gets the inverse navigation. + /// + INavigationBase INavigationBase.Inverse + { + [DebuggerStepThrough] + get => Inverse; + } /// /// Gets the foreign key that defines the relationship this navigation property will navigate. /// IForeignKey ForeignKey { get; } + + /// + /// Gets a value indicating whether the navigation property is defined on the dependent side of the underlying foreign key. + /// + bool IsOnDependent + { + [DebuggerStepThrough] + get => ForeignKey.DependentToPrincipal == this; + } + + /// + /// Gets a value indicating whether the navigation property is a collection property. + /// + bool INavigationBase.IsCollection + { + [DebuggerStepThrough] + get => !IsOnDependent && !ForeignKey.IsUnique; + } + + /// + /// Gets the for this navigation property, if it's a collection + /// navigation. + /// + /// The accessor. + [DebuggerStepThrough] + IClrCollectionAccessor INavigationBase.GetCollectionAccessor() => new ClrCollectionAccessorFactory().Create(this); } } diff --git a/src/EFCore/Metadata/INavigationBase.cs b/src/EFCore/Metadata/INavigationBase.cs new file mode 100644 index 00000000000..5f0f927d7c5 --- /dev/null +++ b/src/EFCore/Metadata/INavigationBase.cs @@ -0,0 +1,46 @@ +// 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 Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata +{ + /// + /// Represents a navigation property which can be used to navigate a relationship. + /// + public interface INavigationBase : IPropertyBase + { + /// + /// Gets the entity type that this navigation property belongs to. + /// + IEntityType DeclaringEntityType { get; } + + /// + /// Gets the entity type that this navigation property will hold an instance(s) of. + /// + IEntityType TargetEntityType { get; } + + /// + /// Gets the inverse navigation. + /// + INavigationBase Inverse { get; } + + /// + /// Gets a value indicating whether the navigation property is a collection property. + /// + bool IsCollection { get; } + + /// + /// Gets a value indicating whether this navigation should be eager loaded by default. + /// + bool IsEagerLoaded + => (bool?)this[CoreAnnotationNames.EagerLoaded] ?? false; + + /// + /// Gets the for this navigation property, if it's a collection + /// navigation. + /// + /// The accessor. + IClrCollectionAccessor GetCollectionAccessor(); + } +} diff --git a/src/EFCore/Metadata/ISkipNavigation.cs b/src/EFCore/Metadata/ISkipNavigation.cs index 1c6ac91d0da..da1f33dfd0c 100644 --- a/src/EFCore/Metadata/ISkipNavigation.cs +++ b/src/EFCore/Metadata/ISkipNavigation.cs @@ -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.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Metadata @@ -9,55 +10,43 @@ namespace Microsoft.EntityFrameworkCore.Metadata /// Represents a navigation property that is part of a relationship /// that is forwarded through a third entity type. /// - public interface ISkipNavigation : IPropertyBase + public interface ISkipNavigation : INavigationBase { - /// - /// Gets the entity type that this navigation belongs to. - /// - IEntityType DeclaringEntityType { get; } - - /// - /// Gets the entity type that this navigation property will hold an instance(s) of. - /// - IEntityType TargetEntityType { get; } - /// /// Gets the association type used by the foreign key. /// - IEntityType AssociationEntityType => IsOnPrincipal ? ForeignKey?.DeclaringEntityType : ForeignKey?.PrincipalEntityType; - - /// - /// Gets the foreign key to the association type. - /// - IForeignKey ForeignKey { get; } + IEntityType AssociationEntityType => IsOnDependent ? ForeignKey?.PrincipalEntityType : ForeignKey?.DeclaringEntityType; /// /// Gets the inverse skip navigation. /// - ISkipNavigation Inverse { get; } + new ISkipNavigation Inverse { get; } /// - /// Gets a value indicating whether the navigation property is a collection property. + /// Gets the inverse navigation. /// - bool IsCollection { get; } + INavigationBase INavigationBase.Inverse + { + [DebuggerStepThrough] + get => Inverse; + } /// - /// Gets a value indicating whether the navigation property is defined on the principal side of the underlying foreign key. + /// Gets the foreign key to the association type. /// - bool IsOnPrincipal { get; } + IForeignKey ForeignKey { get; } /// - /// Gets a value indicating whether this navigation should be eager loaded by default. + /// Gets a value indicating whether the navigation property is defined on the dependent side of the underlying foreign key. /// - bool IsEagerLoaded - => (bool?)this[CoreAnnotationNames.EagerLoaded] ?? false; + bool IsOnDependent { get; } /// - /// Gets the for this navigation property, which must be a collection + /// Gets the for this navigation property, if it's a collection /// navigation. /// /// The accessor. - IClrCollectionAccessor GetCollectionAccessor() + IClrCollectionAccessor INavigationBase.GetCollectionAccessor() => new ClrCollectionAccessorFactory().Create(this); } } diff --git a/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs b/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs index ea8801d2db9..94d862b2234 100644 --- a/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs +++ b/src/EFCore/Metadata/Internal/ClrCollectionAccessorFactory.cs @@ -49,7 +49,7 @@ private static readonly MethodInfo _createObservableHashSet /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IClrCollectionAccessor Create([NotNull] INavigation navigation) - => !navigation.IsCollection() || navigation.IsShadowProperty() ? null : Create(navigation, navigation.GetTargetType()); + => !navigation.IsCollection || navigation.IsShadowProperty() ? null : Create(navigation, navigation.TargetEntityType); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs index fdc4df8297f..c40a023eeca 100644 --- a/src/EFCore/Metadata/Internal/EntityType.cs +++ b/src/EFCore/Metadata/Internal/EntityType.cs @@ -1380,7 +1380,7 @@ private Navigation AddNavigation(MemberIdentity navigationMember, ForeignKey for } Check.DebugAssert( - !GetNavigations().Any(n => n.ForeignKey == foreignKey && n.IsDependentToPrincipal() == pointsToPrincipal), + !GetNavigations().Any(n => n.ForeignKey == foreignKey && n.IsOnDependent == pointsToPrincipal), "There is another navigation corresponding to the same foreign key and pointing in the same direction."); Check.DebugAssert( @@ -1538,7 +1538,7 @@ public virtual SkipNavigation AddSkipNavigation( [NotNull] EntityType targetEntityType, [CanBeNull] ForeignKey foreignKey, bool collection, - bool onPrincipal, + bool onDependent, ConfigurationSource configurationSource) { Check.NotEmpty(name, nameof(name)); @@ -1580,7 +1580,7 @@ public virtual SkipNavigation AddSkipNavigation( targetEntityType, foreignKey, collection, - onPrincipal, + onDependent, configurationSource); _skipNavigations.Add(name, skipNavigation); @@ -3207,8 +3207,8 @@ IMutableSkipNavigation IMutableEntityType.AddSkipNavigation( [NotNull] IMutableEntityType targetEntityType, [NotNull] IMutableForeignKey foreignKey, bool collection, - bool onPrincipal) - => AddSkipNavigation(name, memberInfo, (EntityType)targetEntityType, (ForeignKey)foreignKey, collection, onPrincipal, + bool onDependent) + => AddSkipNavigation(name, memberInfo, (EntityType)targetEntityType, (ForeignKey)foreignKey, collection, onDependent, ConfigurationSource.Explicit); /// @@ -3224,9 +3224,9 @@ IConventionSkipNavigation IConventionEntityType.AddSkipNavigation( [NotNull] IConventionEntityType targetEntityType, [NotNull] IConventionForeignKey foreignKey, bool collection, - bool onPrincipal, + bool onDependent, bool fromDataAnnotation) - => AddSkipNavigation(name, memberInfo, (EntityType)targetEntityType, (ForeignKey)foreignKey, collection, onPrincipal, + => AddSkipNavigation(name, memberInfo, (EntityType)targetEntityType, (ForeignKey)foreignKey, collection, onDependent, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); /// diff --git a/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs b/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs index 679e1e2654a..d0074b5702e 100644 --- a/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs +++ b/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs @@ -338,7 +338,7 @@ public static PropertyCounts CalculateCounts([NotNull] this EntityType entityTyp index: navigationIndex++, originalValueIndex: -1, shadowIndex: navigation.IsShadowProperty() ? shadowIndex++ : -1, - relationshipIndex: navigation.IsCollection() && isNotifying ? -1 : relationshipIndex++, + relationshipIndex: ((INavigation)navigation).IsCollection && isNotifying ? -1 : relationshipIndex++, storeGenerationIndex: -1); navigation.PropertyIndexes = indexes; diff --git a/src/EFCore/Metadata/Internal/ForeignKey.cs b/src/EFCore/Metadata/Internal/ForeignKey.cs index 7559aaac65a..37c3477fb6e 100644 --- a/src/EFCore/Metadata/Internal/ForeignKey.cs +++ b/src/EFCore/Metadata/Internal/ForeignKey.cs @@ -146,6 +146,7 @@ public virtual IEnumerable GetReferencingSkipNavigations() /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource GetConfigurationSource() => _configurationSource; /// @@ -211,6 +212,7 @@ public virtual void SetProperties( /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetPropertiesConfigurationSource() => _propertiesConfigurationSource; /// @@ -234,6 +236,7 @@ public virtual void UpdatePropertiesConfigurationSource(ConfigurationSource conf /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetPrincipalKeyConfigurationSource() => _principalKeyConfigurationSource; /// @@ -254,6 +257,7 @@ public virtual void UpdatePrincipalKeyConfigurationSource(ConfigurationSource co /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetPrincipalEndConfigurationSource() => _principalEndConfigurationSource; /// @@ -310,6 +314,7 @@ public virtual Navigation HasDependentToPrincipal( /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetDependentToPrincipalConfigurationSource() => _dependentToPrincipalConfigurationSource; /// @@ -357,6 +362,7 @@ public virtual Navigation HasPrincipalToDependent( /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetPrincipalToDependentConfigurationSource() => _principalToDependentConfigurationSource; /// @@ -523,6 +529,7 @@ public virtual ForeignKey SetIsUnique(bool? unique, ConfigurationSource configur /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetIsUniqueConfigurationSource() => _isUniqueConfigurationSource; /// @@ -579,6 +586,7 @@ public virtual ForeignKey SetIsRequired(bool? required, ConfigurationSource conf /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetIsRequiredConfigurationSource() => _isRequiredConfigurationSource; /// @@ -641,6 +649,7 @@ public virtual ForeignKey SetDeleteBehavior(DeleteBehavior? deleteBehavior, Conf /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetDeleteBehaviorConfigurationSource() => _deleteBehaviorConfigurationSource; /// @@ -697,6 +706,7 @@ public virtual ForeignKey SetIsOwnership(bool? ownership, ConfigurationSource co /// 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. /// + [DebuggerStepThrough] public virtual ConfigurationSource? GetIsOwnershipConfigurationSource() => _isOwnershipConfigurationSource; /// @@ -1002,7 +1012,10 @@ IConventionNavigation IConventionForeignKey.PrincipalToDependent /// 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. /// - IConventionRelationshipBuilder IConventionForeignKey.Builder => Builder; + IConventionRelationshipBuilder IConventionForeignKey.Builder + { + [DebuggerStepThrough] get => Builder; + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs index 78ba31a8c59..44943638928 100644 --- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs @@ -517,9 +517,7 @@ private InternalPropertyBuilder Property( { var foreignKey = conflictingNavigation.ForeignKey; - var navigationConfigurationSource = conflictingNavigation.IsDependentToPrincipal() - ? foreignKey.GetDependentToPrincipalConfigurationSource() - : foreignKey.GetPrincipalToDependentConfigurationSource(); + var navigationConfigurationSource = conflictingNavigation.GetConfigurationSource(); if (!configurationSource.Overrides(navigationConfigurationSource)) { return null; @@ -610,7 +608,7 @@ private InternalPropertyBuilder Property( } else if (foreignKey.Builder.HasNavigation( (string)null, - conflictingNavigation.IsDependentToPrincipal(), + conflictingNavigation.IsOnDependent, configurationSource.Value) == null) { @@ -772,12 +770,7 @@ public virtual InternalServicePropertyBuilder ServiceProperty( foreach (var conflictingNavigation in Metadata.FindNavigationsInHierarchy(propertyName)) { - var foreignKey = conflictingNavigation.ForeignKey; - - if (!configurationSource.Overrides( - conflictingNavigation.IsDependentToPrincipal() - ? foreignKey.GetDependentToPrincipalConfigurationSource() - : foreignKey.GetPrincipalToDependentConfigurationSource())) + if (!configurationSource.Overrides(conflictingNavigation.GetConfigurationSource())) { return null; } @@ -809,7 +802,7 @@ public virtual InternalServicePropertyBuilder ServiceProperty( } else if (foreignKey.Builder.HasNavigation( (string)null, - conflictingNavigation.IsDependentToPrincipal(), + conflictingNavigation.IsOnDependent, configurationSource) == null) { @@ -832,7 +825,7 @@ public virtual InternalServicePropertyBuilder ServiceProperty( public virtual bool CanAddNavigation([NotNull] string navigationName, ConfigurationSource configurationSource) => !IsIgnored(navigationName, configurationSource) && Metadata.FindNavigationsInHierarchy(navigationName).All( - n => n.ForeignKey.Builder.CanSetNavigation((string)null, n.IsDependentToPrincipal(), configurationSource)); + n => n.ForeignKey.Builder.CanSetNavigation((string)null, n.IsOnDependent, configurationSource)); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -894,14 +887,11 @@ public virtual InternalEntityTypeBuilder Ignore([NotNull] string name, Configura var foreignKey = navigation.ForeignKey; Check.DebugAssert(navigation.DeclaringEntityType == Metadata, "navigation.DeclaringEntityType != Metadata"); - var isDependent = navigation.IsDependentToPrincipal(); - var navigationConfigurationSource = isDependent - ? foreignKey.GetDependentToPrincipalConfigurationSource() - : foreignKey.GetPrincipalToDependentConfigurationSource(); + var navigationConfigurationSource = navigation.GetConfigurationSource(); if (foreignKey.GetConfigurationSource() != navigationConfigurationSource) { var navigationRemoved = foreignKey.Builder.HasNavigation( - (MemberInfo)null, isDependent, configurationSource); + (MemberInfo)null, navigation.IsOnDependent, configurationSource); Check.DebugAssert(navigationRemoved != null, "navigationRemoved is null"); } else @@ -1016,10 +1006,7 @@ private bool CanIgnore(string name, ConfigurationSource configurationSource, boo return false; } - var isDependent = navigation.IsDependentToPrincipal(); - var navigationConfigurationSource = isDependent - ? foreignKey.GetDependentToPrincipalConfigurationSource() - : foreignKey.GetPrincipalToDependentConfigurationSource(); + var navigationConfigurationSource = navigation.GetConfigurationSource(); if (foreignKey.GetConfigurationSource() != navigationConfigurationSource) { if (!configurationSource.Overrides(navigationConfigurationSource)) @@ -2534,7 +2521,7 @@ private InternalRelationshipBuilder HasOwnership( var existingNavigation = Metadata.FindNavigation(navigation.Name); if (existingNavigation != null) { - if (existingNavigation.GetTargetType().Name == targetEntityType.Name) + if (existingNavigation.TargetEntityType.Name == targetEntityType.Name) { var existingOwnedEntityType = existingNavigation.ForeignKey.DeclaringEntityType; if (existingOwnedEntityType.HasDefiningNavigation()) @@ -2572,7 +2559,7 @@ private InternalRelationshipBuilder HasOwnership( ownershipBuilder = ownershipBuilder .IsRequired(true, configurationSource) ?.HasEntityTypes( - Metadata, ownershipBuilder.Metadata.FindNavigationsFromInHierarchy(Metadata).Single().GetTargetType(), + Metadata, ownershipBuilder.Metadata.FindNavigationsFromInHierarchy(Metadata).Single().TargetEntityType, configurationSource) ?.HasNavigations(inverse, navigation, configurationSource) ?.IsOwnership(true, configurationSource); @@ -2840,7 +2827,7 @@ public virtual InternalEntityTypeBuilder GetTargetEntityTypeBuilder( } targetEntityTypeBuilder = - entityType.FindNavigation(navigationInfo.GetSimpleMemberName())?.GetTargetType().Builder + entityType.FindNavigation(navigationInfo.GetSimpleMemberName())?.TargetEntityType.Builder ?? entityType.Model.FindEntityType( targetClrType, navigationInfo.GetSimpleMemberName(), entityType)?.Builder; diff --git a/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs b/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs index 50349df75d5..d2b1610363a 100644 --- a/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs @@ -977,10 +977,10 @@ public virtual bool CanSetIsEagerLoaded( bool pointsToPrincipal, ConfigurationSource? configurationSource) { - var navigation = pointsToPrincipal ? Metadata.DependentToPrincipal : Metadata.PrincipalToDependent; + IConventionNavigation navigation = pointsToPrincipal ? Metadata.DependentToPrincipal : Metadata.PrincipalToDependent; return navigation != null && (configurationSource.Overrides(navigation.GetIsEagerLoadedConfigurationSource()) - || navigation.IsEagerLoaded() == eagerLoaded); + || navigation.IsEagerLoaded == eagerLoaded); } /// diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs index 690babbd114..73820891e01 100644 --- a/src/EFCore/Metadata/Internal/Model.cs +++ b/src/EFCore/Metadata/Internal/Model.cs @@ -528,7 +528,7 @@ public virtual EntityType FindActualEntityType([NotNull] EntityType entityType) ? entityType : (entityType.HasDefiningNavigation() ? FindActualEntityType(entityType.DefiningEntityType) - ?.FindNavigation(entityType.DefiningNavigationName)?.GetTargetType() + ?.FindNavigation(entityType.DefiningNavigationName)?.TargetEntityType : FindEntityType(entityType.Name)); /// diff --git a/src/EFCore/Metadata/Internal/Navigation.cs b/src/EFCore/Metadata/Internal/Navigation.cs index 1fe7a061292..a075f9baa0e 100644 --- a/src/EFCore/Metadata/Internal/Navigation.cs +++ b/src/EFCore/Metadata/Internal/Navigation.cs @@ -74,9 +74,10 @@ public Navigation( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual EntityType DeclaringEntityType - => this.IsDependentToPrincipal() - ? ForeignKey.DeclaringEntityType - : ForeignKey.PrincipalEntityType; + { + [DebuggerStepThrough] + get => (EntityType)((INavigation)this).DeclaringEntityType; + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -86,9 +87,45 @@ public virtual EntityType DeclaringEntityType /// public override TypeBase DeclaringType { - [DebuggerStepThrough] get => DeclaringEntityType; + [DebuggerStepThrough] + get => (EntityType)((INavigation)this).DeclaringEntityType; + } + + /// + /// 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. + /// + public virtual EntityType TargetEntityType + { + [DebuggerStepThrough] + get => (EntityType)((INavigationBase)this).TargetEntityType; } + /// + /// 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. + /// + public virtual bool IsOnDependent + { + [DebuggerStepThrough] + get => ForeignKey.DependentToPrincipal == this; + } + + /// + /// 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. + /// + public virtual ConfigurationSource GetConfigurationSource() + => (ConfigurationSource)(IsOnDependent + ? ForeignKey.GetDependentToPrincipalConfigurationSource() + : ForeignKey.GetPrincipalToDependentConfigurationSource()); + /// /// 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 @@ -196,11 +233,11 @@ public static bool IsCompatible( /// 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. /// - [DebuggerStepThrough] - public virtual Navigation FindInverse() - => this.IsDependentToPrincipal() - ? ForeignKey.PrincipalToDependent - : ForeignKey.DependentToPrincipal; + public virtual Navigation Inverse + { + [DebuggerStepThrough] + get => (Navigation)((INavigationBase)this).Inverse; + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -208,11 +245,21 @@ public virtual Navigation FindInverse() /// 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. /// - [DebuggerStepThrough] - public virtual EntityType GetTargetType() - => this.IsDependentToPrincipal() - ? ForeignKey.PrincipalEntityType - : ForeignKey.DeclaringEntityType; + public virtual Navigation SetInverse([CanBeNull] string inverseName, ConfigurationSource configurationSource) + => IsOnDependent + ? ForeignKey.HasPrincipalToDependent(inverseName, configurationSource) + : ForeignKey.HasPrincipalToDependent(inverseName, configurationSource); + + /// + /// 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. + /// + public virtual Navigation SetInverse([CanBeNull] MemberInfo inverse, ConfigurationSource configurationSource) + => IsOnDependent + ? ForeignKey.HasPrincipalToDependent(inverse, configurationSource) + : ForeignKey.HasPrincipalToDependent(inverse, configurationSource); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -266,59 +313,20 @@ IForeignKey INavigation.ForeignKey [DebuggerStepThrough] get => ForeignKey; } - /// - /// 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. - /// - IMutableForeignKey IMutableNavigation.ForeignKey - { - [DebuggerStepThrough] get => ForeignKey; - } - - /// - /// 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. - /// - IEntityType INavigation.DeclaringEntityType - { - [DebuggerStepThrough] get => DeclaringEntityType; - } + [DebuggerStepThrough] + IMutableNavigation IMutableNavigation.SetInverse([CanBeNull] string inverseName) + => SetInverse(inverseName, ConfigurationSource.Explicit); - /// - /// 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. - /// - IMutableEntityType IMutableNavigation.DeclaringEntityType - { - [DebuggerStepThrough] get => DeclaringEntityType; - } + [DebuggerStepThrough] + IMutableNavigation IMutableNavigation.SetInverse([CanBeNull] MemberInfo inverse) + => SetInverse(inverse, ConfigurationSource.Explicit); - /// - /// 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. - /// - IConventionEntityType IConventionNavigation.DeclaringEntityType - { - [DebuggerStepThrough] get => DeclaringEntityType; - } + [DebuggerStepThrough] + IConventionNavigation IConventionNavigation.SetInverse([CanBeNull] string inverseName, bool fromDataAnnotation) + => SetInverse(inverseName, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); - /// - /// 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. - /// - IConventionForeignKey IConventionNavigation.ForeignKey - { - [DebuggerStepThrough] get => ForeignKey; - } + [DebuggerStepThrough] + IConventionNavigation IConventionNavigation.SetInverse([CanBeNull] MemberInfo inverse, bool fromDataAnnotation) + => SetInverse(inverse, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); } } diff --git a/src/EFCore/Metadata/Internal/NavigationExtensions.cs b/src/EFCore/Metadata/Internal/NavigationExtensions.cs index 6e276d484f8..fcb402409c3 100644 --- a/src/EFCore/Metadata/Internal/NavigationExtensions.cs +++ b/src/EFCore/Metadata/Internal/NavigationExtensions.cs @@ -57,18 +57,18 @@ public static string ToDebugString( builder.Append(navigation.ClrType?.ShortDisplayName()).Append(")"); - if (navigation.IsCollection()) + if (navigation.IsCollection) { builder.Append(" Collection"); } - builder.Append(navigation.IsDependentToPrincipal() ? " ToPrincipal " : " ToDependent "); + builder.Append(navigation.IsOnDependent ? " ToPrincipal " : " ToDependent "); - builder.Append(navigation.GetTargetType().DisplayName()); + builder.Append(navigation.TargetEntityType.DisplayName()); - if (navigation.FindInverse() != null) + if (navigation.Inverse != null) { - builder.Append(" Inverse: ").Append(navigation.FindInverse().Name); + builder.Append(" Inverse: ").Append(navigation.Inverse.Name); } if (navigation.GetPropertyAccessMode() != PropertyAccessMode.PreferField) diff --git a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs index a1571b12951..940327625f3 100644 --- a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs +++ b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs @@ -114,7 +114,7 @@ public static bool TryGetMemberInfo( var setterProperty = propertyInfo?.FindSetterProperty(); var getterProperty = propertyInfo?.FindGetterProperty(); - var isCollectionNav = (propertyBase as INavigation)?.IsCollection() == true; + var isCollectionNav = (propertyBase as INavigation)?.IsCollection == true; var hasField = fieldInfo != null; var hasSetter = setterProperty != null; var hasGetter = getterProperty != null; diff --git a/src/EFCore/Metadata/Internal/SkipNavigation.cs b/src/EFCore/Metadata/Internal/SkipNavigation.cs index 305390adff8..6d68779d319 100644 --- a/src/EFCore/Metadata/Internal/SkipNavigation.cs +++ b/src/EFCore/Metadata/Internal/SkipNavigation.cs @@ -42,7 +42,7 @@ public SkipNavigation( [NotNull] EntityType targetEntityType, [CanBeNull] ForeignKey foreignKey, bool collection, - bool onPrincipal, + bool onDependent, ConfigurationSource configurationSource) : base(name, propertyInfo, fieldInfo) { @@ -52,19 +52,19 @@ public SkipNavigation( DeclaringEntityType = declaringEntityType; TargetEntityType = targetEntityType; IsCollection = collection; - IsOnPrincipal = onPrincipal; + IsOnDependent = onDependent; _configurationSource = configurationSource; Builder = new InternalSkipNavigationBuilder(this, targetEntityType.Model.Builder); if (foreignKey != null) { - var expectedEntityType = IsOnPrincipal ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType; + var expectedEntityType = IsOnDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType; if (expectedEntityType != DeclaringEntityType) { - var message = IsOnPrincipal - ? CoreStrings.SkipNavigationWrongPrincipalType( + var message = IsOnDependent + ? CoreStrings.SkipNavigationWrongDependentType( Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName(), foreignKey.Properties.Format()) - : CoreStrings.SkipNavigationWrongDependentType( + : CoreStrings.SkipNavigationWrongPrincipalType( Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName(), foreignKey.Properties.Format()); throw new InvalidOperationException(message); } @@ -134,7 +134,7 @@ private void ProcessForeignKey(ForeignKey foreignKey) /// 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. /// - public virtual EntityType AssociationEntityType => IsOnPrincipal ? ForeignKey?.DeclaringEntityType : ForeignKey?.PrincipalEntityType; + public virtual EntityType AssociationEntityType => IsOnDependent ? ForeignKey?.PrincipalEntityType : ForeignKey?.DeclaringEntityType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -166,7 +166,7 @@ private void ProcessForeignKey(ForeignKey foreignKey) /// 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. /// - public virtual bool IsOnPrincipal { get; } + public virtual bool IsOnDependent { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -215,13 +215,13 @@ public virtual ForeignKey SetForeignKey([CanBeNull] ForeignKey foreignKey, Confi : foreignKey; } - var expectedEntityType = IsOnPrincipal ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType; + var expectedEntityType = IsOnDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType; if (expectedEntityType != DeclaringEntityType) { - var message = IsOnPrincipal - ? CoreStrings.SkipNavigationForeignKeyWrongPrincipalType( + var message = IsOnDependent + ? CoreStrings.SkipNavigationForeignKeyWrongDependentType( foreignKey.Properties.Format(), Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName()) - : CoreStrings.SkipNavigationForeignKeyWrongDependentType( + : CoreStrings.SkipNavigationForeignKeyWrongPrincipalType( foreignKey.Properties.Format(), Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName()); throw new InvalidOperationException(message); } @@ -372,25 +372,13 @@ IConventionSkipNavigationBuilder IConventionSkipNavigation.Builder get => Builder; } - IEntityType ISkipNavigation.DeclaringEntityType + IEntityType INavigationBase.DeclaringEntityType { [DebuggerStepThrough] get => DeclaringEntityType; } - IEntityType ISkipNavigation.TargetEntityType - { - [DebuggerStepThrough] - get => TargetEntityType; - } - - IMutableEntityType IMutableSkipNavigation.TargetEntityType - { - [DebuggerStepThrough] - get => TargetEntityType; - } - - IConventionEntityType IConventionSkipNavigation.TargetEntityType + IEntityType INavigationBase.TargetEntityType { [DebuggerStepThrough] get => TargetEntityType; @@ -402,24 +390,10 @@ IForeignKey ISkipNavigation.ForeignKey get => ForeignKey; } - IMutableForeignKey IMutableSkipNavigation.ForeignKey - { - [DebuggerStepThrough] - get => ForeignKey; - } - - IConventionForeignKey IConventionSkipNavigation.ForeignKey - { - [DebuggerStepThrough] - get => ForeignKey; - } - - [DebuggerStepThrough] IMutableForeignKey IMutableSkipNavigation.SetForeignKey([CanBeNull] IMutableForeignKey foreignKey) => SetForeignKey((ForeignKey)foreignKey, ConfigurationSource.Explicit); - [DebuggerStepThrough] IConventionForeignKey IConventionSkipNavigation.SetForeignKey([CanBeNull] IConventionForeignKey foreignKey, bool fromDataAnnotation) => SetForeignKey((ForeignKey)foreignKey, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); @@ -430,20 +404,8 @@ ISkipNavigation ISkipNavigation.Inverse get => Inverse; } - IMutableSkipNavigation IMutableSkipNavigation.Inverse - { - [DebuggerStepThrough] - get => Inverse; - } - - IConventionSkipNavigation IConventionSkipNavigation.Inverse - { - [DebuggerStepThrough] - get => Inverse; - } - [DebuggerStepThrough] - IConventionSkipNavigation IMutableSkipNavigation.SetInverse([CanBeNull] IMutableSkipNavigation inverse) + IMutableSkipNavigation IMutableSkipNavigation.SetInverse([CanBeNull] IMutableSkipNavigation inverse) => SetInverse((SkipNavigation)inverse, ConfigurationSource.Explicit); [DebuggerStepThrough] diff --git a/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs b/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs index cb3c0ac4ab1..109cb9b0b9a 100644 --- a/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs @@ -866,7 +866,7 @@ private Expression RewriteNullEquality( [NotNull] Expression nonNullExpression, [CanBeNull] INavigation lastNavigation) { - if (lastNavigation?.IsCollection() == true) + if (lastNavigation?.IsCollection == true) { // collection navigation is only null if its parent entity is null (null propagation thru navigation) // it is probable that user wanted to see if the collection is (not) empty @@ -898,8 +898,8 @@ private Expression RewriteEntityEquality( [NotNull] Expression right, [CanBeNull] INavigation rightNavigation, bool subqueryTraversed) { - if (leftNavigation?.IsCollection() == true - || rightNavigation?.IsCollection() == true) + if (leftNavigation?.IsCollection == true + || rightNavigation?.IsCollection == true) { if (leftNavigation?.Equals(rightNavigation) == true) { @@ -1168,7 +1168,7 @@ public virtual Expression TraverseProperty(string propertyName, Expression desti return EntityType.FindNavigation(propertyName) is INavigation navigation ? new EntityReferenceExpression( destinationExpression, - navigation.GetTargetType(), + navigation.TargetEntityType, navigation, null, SubqueryTraversed) diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs index 93aab9fbc7e..284290a72d4 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs @@ -146,7 +146,7 @@ protected Expression ExpandNavigation( return expansion; } - var targetType = navigation.GetTargetType(); + var targetType = navigation.TargetEntityType; if (targetType.HasDefiningNavigation() || targetType.IsOwned()) { @@ -158,7 +158,7 @@ protected Expression ExpandNavigation( } var ownedExpansion = new OwnedNavigationReference(root, navigation, ownedEntityReference); - if (navigation.IsCollection()) + if (navigation.IsCollection) { var elementType = ownedExpansion.Type.TryGetSequenceType(); var subquery = Expression.Call( @@ -191,7 +191,7 @@ protected Expression ExpandNavigation( // This is FirstOrDefault ending so we need to push down properties. var temporaryParameter = Expression.Parameter(root.Type); var temporaryKey = temporaryParameter.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? navigation.ForeignKey.Properties : navigation.ForeignKey.PrincipalKey.Properties, makeNullable: true); @@ -205,14 +205,14 @@ protected Expression ExpandNavigation( else { outerKey = root.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? navigation.ForeignKey.Properties : navigation.ForeignKey.PrincipalKey.Properties, makeNullable: true); } var innerKey = innerParameter.CreateKeyAccessExpression( - navigation.IsDependentToPrincipal() + navigation.IsOnDependent ? navigation.ForeignKey.PrincipalKey.Properties : navigation.ForeignKey.Properties, makeNullable: true); @@ -230,7 +230,7 @@ protected Expression ExpandNavigation( } } - if (navigation.IsCollection()) + if (navigation.IsCollection) { var outerKeyFirstProperty = outerKey is NewExpression newExpression ? ((UnaryExpression)((NewArrayExpression)newExpression.Arguments[0]).Expressions[0]).Operand @@ -276,7 +276,7 @@ protected Expression ExpandNavigation( var innerJoin = !entityReference.IsOptional && !derivedTypeConversion - && navigation.IsDependentToPrincipal() + && navigation.IsOnDependent && navigation.ForeignKey.IsRequired; if (!innerJoin) @@ -486,7 +486,7 @@ private void VerifyNoCycles(IncludeTreeNode includeTreeNode) { var navigation = keyValuePair.Key; var referenceIncludeTreeNode = keyValuePair.Value; - var inverseNavigation = navigation.FindInverse(); + var inverseNavigation = navigation.Inverse; if (inverseNavigation != null && referenceIncludeTreeNode.ContainsKey(inverseNavigation)) { @@ -517,10 +517,10 @@ private Expression ExpandIncludesHelper(Expression root, EntityReference entityR var included = ExpandNavigation(convertedRoot, entityReference, navigation, converted); // Collection will expand it's includes when reducing the navigationExpansionExpression - if (!navigation.IsCollection()) + if (!navigation.IsCollection) { - var innerEntityReference = navigation.GetTargetType().HasDefiningNavigation() - || navigation.GetTargetType().IsOwned() + var innerEntityReference = navigation.TargetEntityType.HasDefiningNavigation() + || navigation.TargetEntityType.IsOwned() ? ((OwnedNavigationReference)included).EntityReference : (EntityReference)((NavigationTreeExpression)included).Value; diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs index 582f66d43c0..aafaa8fe2d5 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs @@ -109,7 +109,7 @@ public virtual IncludeTreeNode AddNavigation(INavigation navigation) } else { - this[navigation] = new IncludeTreeNode(navigation.GetTargetType(), null); + this[navigation] = new IncludeTreeNode(navigation.TargetEntityType, null); } return this[navigation]; diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs index 38e1d287fa2..f7a34f72d00 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs @@ -1433,7 +1433,7 @@ private Expression UnwrapCollectionMaterialization(Expression expression) } return expression is OwnedNavigationReference ownedNavigationReference - && ownedNavigationReference.Navigation.IsCollection() + && ownedNavigationReference.Navigation.IsCollection ? CreateNavigationExpansionExpression( Expression.Call( QueryableMethods.AsQueryable.MakeGenericMethod(ownedNavigationReference.Type.TryGetSequenceType()), @@ -1461,7 +1461,7 @@ private static void PopulateEagerLoadedNavigations(IncludeTreeNode includeTreeNo var outboundNavigations = entityType.GetNavigations() .Concat(entityType.GetDerivedNavigations()) - .Where(n => n.IsEagerLoaded()); + .Where(n => n.IsEagerLoaded); foreach (var navigation in outboundNavigations) { diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs index ca586173357..1799c428ef9 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs @@ -169,7 +169,7 @@ public void Sets_owned_type_keys() Assert.Empty(reporter.Messages); Assert.Equal( nameof(BlogDetails.BlogId), - model.FindEntityType(typeof(Blog)).FindNavigation(nameof(Blog.Details)).GetTargetType().FindPrimaryKey().Properties.Single() + model.FindEntityType(typeof(Blog)).FindNavigation(nameof(Blog.Details)).TargetEntityType.FindPrimaryKey().Properties.Single() .Name); } diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs index 23a7b9ba2c7..ae2354a40a3 100644 --- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs +++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs @@ -1273,7 +1273,7 @@ public virtual void Owned_types_are_stored_in_snapshot() var entityWithStringKey = o.FindEntityType(typeof(EntityWithStringKey)); Assert.Same( entityWithStringKey, - ownedType1.FindNavigation(nameof(EntityWithTwoProperties.EntityWithStringKey)).GetTargetType()); + ownedType1.FindNavigation(nameof(EntityWithTwoProperties.EntityWithStringKey)).TargetEntityType); Assert.Equal(nameof(EntityWithStringKey), entityWithStringKey.GetTableName()); var ownership2 = entityWithStringKey.FindNavigation(nameof(EntityWithStringKey.Properties)).ForeignKey; @@ -1294,7 +1294,7 @@ public virtual void Owned_types_are_stored_in_snapshot() Assert.Null(owned2index2.GetFilter()); Assert.Equal(nameof(EntityWithStringProperty), ownedType2.GetTableName()); - Assert.Same(entityWithOneProperty, ownedType2.GetNavigations().Single().GetTargetType()); + Assert.Same(entityWithOneProperty, ownedType2.GetNavigations().Single().TargetEntityType); }); } @@ -1431,23 +1431,23 @@ public virtual void Weak_owned_types_are_stored_in_snapshot() var order = o.FindEntityType(typeof(Order).FullName); Assert.Equal(1, order.PropertyCount()); - var orderInfo = order.FindNavigation(nameof(Order.OrderInfo)).GetTargetType(); + var orderInfo = order.FindNavigation(nameof(Order.OrderInfo)).TargetEntityType; Assert.Equal(1, orderInfo.PropertyCount()); - var orderInfoAddress = orderInfo.FindNavigation(nameof(OrderInfo.StreetAddress)).GetTargetType(); + var orderInfoAddress = orderInfo.FindNavigation(nameof(OrderInfo.StreetAddress)).TargetEntityType; Assert.Equal(2, orderInfoAddress.PropertyCount()); - var orderBillingDetails = order.FindNavigation(nameof(Order.OrderBillingDetails)).GetTargetType(); + var orderBillingDetails = order.FindNavigation(nameof(Order.OrderBillingDetails)).TargetEntityType; Assert.Equal(1, orderBillingDetails.PropertyCount()); - var orderBillingDetailsAddress = orderBillingDetails.FindNavigation(nameof(OrderDetails.StreetAddress)).GetTargetType(); + var orderBillingDetailsAddress = orderBillingDetails.FindNavigation(nameof(OrderDetails.StreetAddress)).TargetEntityType; Assert.Equal(2, orderBillingDetailsAddress.PropertyCount()); - var orderShippingDetails = order.FindNavigation(nameof(Order.OrderShippingDetails)).GetTargetType(); + var orderShippingDetails = order.FindNavigation(nameof(Order.OrderShippingDetails)).TargetEntityType; Assert.Equal(1, orderShippingDetails.PropertyCount()); var orderShippingDetailsAddress = - orderShippingDetails.FindNavigation(nameof(OrderDetails.StreetAddress)).GetTargetType(); + orderShippingDetails.FindNavigation(nameof(OrderDetails.StreetAddress)).TargetEntityType; Assert.Equal(2, orderShippingDetailsAddress.PropertyCount()); }); } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs index 44c4f8657d4..b2d8426aa8a 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs @@ -64,11 +64,11 @@ public Post() { var postType = model.FindEntityType("TestNamespace.Post"); var authorNavigation = postType.FindNavigation("Author"); - Assert.True(authorNavigation.IsDependentToPrincipal()); + Assert.True(authorNavigation.IsOnDependent); Assert.Equal("TestNamespace.Person", authorNavigation.ForeignKey.PrincipalEntityType.Name); var contributionsNav = postType.FindNavigation("Contributions"); - Assert.False(contributionsNav.IsDependentToPrincipal()); + Assert.False(contributionsNav.IsOnDependent); Assert.Equal("TestNamespace.Contribution", contributionsNav.ForeignKey.DeclaringEntityType.Name); }); } @@ -122,7 +122,7 @@ public partial class Post var foreignKeyProperty = Assert.Single(blogNavigation.ForeignKey.Properties); Assert.Equal("BlogId", foreignKeyProperty.Name); - var inverseNavigation = blogNavigation.FindInverse(); + var inverseNavigation = blogNavigation.Inverse; Assert.Equal("TestNamespace.Blog", inverseNavigation.DeclaringEntityType.Name); Assert.Equal("Posts", inverseNavigation.Name); }); @@ -177,7 +177,7 @@ public partial class Post var foreignKeyProperty = Assert.Single(blogNavigation.ForeignKey.Properties); Assert.Equal("Blog", foreignKeyProperty.Name); - var inverseNavigation = blogNavigation.FindInverse(); + var inverseNavigation = blogNavigation.Inverse; Assert.Equal("TestNamespace.Blog", inverseNavigation.DeclaringEntityType.Name); Assert.Equal("Posts", inverseNavigation.Name); }); @@ -238,7 +238,7 @@ public partial class Post var foreignKeyProperty = Assert.Single(blogNavigation.ForeignKey.Properties); Assert.Equal("BlogId", foreignKeyProperty.Name); - var inverseNavigation = blogNavigation.FindInverse(); + var inverseNavigation = blogNavigation.Inverse; Assert.Equal("TestNamespace.Blog", inverseNavigation.DeclaringEntityType.Name); Assert.Equal("Posts", inverseNavigation.Name); @@ -247,7 +247,7 @@ public partial class Post var originalForeignKeyProperty = Assert.Single(originalBlogNavigation.ForeignKey.Properties); Assert.Equal("OriginalBlogId", originalForeignKeyProperty.Name); - var originalInverseNavigation = originalBlogNavigation.FindInverse(); + var originalInverseNavigation = originalBlogNavigation.Inverse; Assert.Equal("TestNamespace.Blog", originalInverseNavigation.DeclaringEntityType.Name); Assert.Equal("OriginalPosts", originalInverseNavigation.Name); }); diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index e6ae29bd99f..f3827c80152 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -1594,9 +1594,9 @@ public virtual void InversePropertyAttribute_removes_ambiguity() Assert.Equal( nameof(Book.Label), - model.FindEntityType(typeof(BookLabel)).FindNavigation(nameof(BookLabel.Book)).FindInverse()?.Name); + model.FindEntityType(typeof(BookLabel)).FindNavigation(nameof(BookLabel.Book)).Inverse?.Name); - Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel)).FindInverse()); + Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel)).Inverse); } [ConditionalFact] @@ -1610,8 +1610,8 @@ public virtual void InversePropertyAttribute_removes_ambiguity_with_base_type() Assert.Equal( nameof(Book.Label), model.FindEntityType(typeof(SpecialBookLabel)) - .FindNavigation(nameof(SpecialBookLabel.Book)).FindInverse()?.Name); - Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel)).FindInverse()); + .FindNavigation(nameof(SpecialBookLabel.Book)).Inverse?.Name); + Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel)).Inverse); modelBuilder.Entity().HasBaseType((Type)null); @@ -1634,7 +1634,7 @@ public virtual void InversePropertyAttribute_removes_ambiguity_with_base_type_ig Assert.Null(model.FindEntityType(typeof(BookLabel))); Assert.Equal( nameof(Book.Label), model.FindEntityType(typeof(SpecialBookLabel)) - .FindNavigation(nameof(SpecialBookLabel.Book)).FindInverse()?.Name); + .FindNavigation(nameof(SpecialBookLabel.Book)).Inverse?.Name); Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel))); } @@ -1665,7 +1665,7 @@ public virtual void InversePropertyAttribute_from_ignored_base_can_be_ignored_to Assert.Null(model.FindEntityType(typeof(BookLabel))); Assert.Equal( nameof(Book.Label), model.FindEntityType(typeof(SpecialBookLabel)) - .FindNavigation(nameof(SpecialBookLabel.Book)).FindInverse()?.Name); + .FindNavigation(nameof(SpecialBookLabel.Book)).Inverse?.Name); Assert.Null(model.FindEntityType(typeof(Book)).FindNavigation(nameof(Book.AlternateLabel))); } @@ -1683,10 +1683,10 @@ public virtual void InversePropertyAttribute_removes_ambiguity_from_the_ambiguou Assert.Null(model.FindEntityType(typeof(BookLabel))); Assert.Equal( nameof(Book.Label), model.FindEntityType(typeof(ExtraSpecialBookLabel)) - .FindNavigation(nameof(ExtraSpecialBookLabel.Book)).FindInverse()?.Name); + .FindNavigation(nameof(ExtraSpecialBookLabel.Book)).Inverse?.Name); Assert.Null( model.FindEntityType(typeof(ExtraSpecialBookLabel)) - .FindNavigation(nameof(ExtraSpecialBookLabel.ExtraSpecialBook)).FindInverse()); + .FindNavigation(nameof(ExtraSpecialBookLabel.ExtraSpecialBook)).Inverse); } protected class Book @@ -1773,11 +1773,11 @@ public virtual void InversePropertyAttribute_removes_ambiguity_when_combined_wit modelBuilder.Entity(); var accountNavigation = model.FindEntityType(typeof(Relation)).FindNavigation(nameof(Relation.AccountManager)); - Assert.Equal(nameof(User.AccountManagerRelations), accountNavigation?.FindInverse()?.Name); + Assert.Equal(nameof(User.AccountManagerRelations), accountNavigation?.Inverse?.Name); Assert.Equal(nameof(Relation.AccountId), accountNavigation?.ForeignKey.Properties.First().Name); var salesNavigation = model.FindEntityType(typeof(Relation)).FindNavigation(nameof(Relation.SalesManager)); - Assert.Equal(nameof(User.SalesManagerRelations), salesNavigation?.FindInverse()?.Name); + Assert.Equal(nameof(User.SalesManagerRelations), salesNavigation?.Inverse?.Name); Assert.Equal(nameof(Relation.SalesId), salesNavigation?.ForeignKey.Properties.First().Name); Validate(modelBuilder); @@ -1815,8 +1815,8 @@ public virtual void InversePropertyAttribute_removes_ambiguity_with_base_type_bi var modelBuilder = CreateModelBuilder(); var qEntity = modelBuilder.Entity().Metadata; - Assert.Equal(nameof(P.QRef), qEntity.FindNavigation(nameof(Q.PRef)).FindInverse().Name); - Assert.Equal(nameof(E.QRefDerived), qEntity.FindNavigation(nameof(Q.ERef)).FindInverse().Name); + Assert.Equal(nameof(P.QRef), qEntity.FindNavigation(nameof(Q.PRef)).Inverse.Name); + Assert.Equal(nameof(E.QRefDerived), qEntity.FindNavigation(nameof(Q.ERef)).Inverse.Name); } public class Q @@ -1855,10 +1855,10 @@ public virtual void InversePropertyAttribute_is_noop_in_unambiguous_models() Assert.Equal( nameof(Post7698.BlogNav), - model.FindEntityType(typeof(Blog7698)).FindNavigation(nameof(Blog7698.PostNav)).FindInverse().Name); + model.FindEntityType(typeof(Blog7698)).FindNavigation(nameof(Blog7698.PostNav)).Inverse.Name); Assert.Equal( nameof(SpecialPost7698.BlogInverseNav), - model.FindEntityType(typeof(Blog7698)).FindNavigation(nameof(Blog7698.ASpecialPostNav)).FindInverse().Name); + model.FindEntityType(typeof(Blog7698)).FindNavigation(nameof(Blog7698.ASpecialPostNav)).Inverse.Name); } protected class Blog7698 diff --git a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs index 9c6746d1f84..128aa3e4ded 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs @@ -145,7 +145,7 @@ private static void CloneNavigations(IEntityType sourceEntityType, IMutableEntit navigation.ForeignKey.PrincipalKey.Properties.Select( p => targetPrincipalEntityType.FindProperty(p.Name)).ToList()), targetPrincipalEntityType); - var clonedNavigation = navigation.IsDependentToPrincipal() + var clonedNavigation = navigation.IsOnDependent ? (navigation.GetIdentifyingMemberInfo() != null ? targetForeignKey.HasDependentToPrincipal(navigation.GetIdentifyingMemberInfo()) : targetForeignKey.HasDependentToPrincipal(navigation.Name)) diff --git a/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/AppendCorrelatedCollectionExpressionMutator.cs b/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/AppendCorrelatedCollectionExpressionMutator.cs index fb28c348984..91e9eb2535f 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/AppendCorrelatedCollectionExpressionMutator.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/AppendCorrelatedCollectionExpressionMutator.cs @@ -17,7 +17,7 @@ public AppendCorrelatedCollectionExpressionMutator(DbContext context) } private bool ContainsCollectionNavigation(Type type) - => Context.Model.FindEntityType(type)?.GetNavigations().Any(n => n.IsCollection()) ?? false; + => Context.Model.FindEntityType(type)?.GetNavigations().Any(n => n.IsCollection) ?? false; public override bool IsValid(Expression expression) => IsQueryableResult(expression) @@ -27,7 +27,7 @@ public override bool IsValid(Expression expression) public override Expression Apply(Expression expression, Random random) { var typeArgument = expression.Type.GetGenericArguments()[0]; - var navigations = Context.Model.FindEntityType(typeArgument).GetNavigations().Where(n => n.IsCollection()).ToList(); + var navigations = Context.Model.FindEntityType(typeArgument).GetNavigations().Where(n => n.IsCollection).ToList(); var i = random.Next(navigations.Count); var navigation = navigations[i]; diff --git a/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/InjectWhereExpressionMutator.cs b/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/InjectWhereExpressionMutator.cs index ab9176d7f3d..94c541db8d3 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/InjectWhereExpressionMutator.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/QueryTestGeneration/InjectWhereExpressionMutator.cs @@ -77,7 +77,7 @@ public override Expression Apply(Expression expression, Random random) { var entityType = Context.Model.FindEntityType(typeArgument); var navigations = entityType.GetNavigations().ToList(); - var collectionNavigations = navigations.Where(n => n.IsCollection()).ToList(); + var collectionNavigations = navigations.Where(n => n.IsCollection).ToList(); var collectionNavigation = random.Choose(collectionNavigations); if (collectionNavigation != null) diff --git a/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs b/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs index ca1d1d434bf..b32e36246e0 100644 --- a/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs +++ b/test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs @@ -494,10 +494,10 @@ public virtual void Passes_on_valid_many_to_many_navigations() orderProductEntity.SetPrimaryKey(new[] { orderProductForeignKey.Properties.Single(), productOrderForeignKey.Properties.Single() }); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); var ordersNavigation = productEntity.AddSkipNavigation( - nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, true); + nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, false); productsNavigation.SetInverse(ordersNavigation); ordersNavigation.SetInverse(productsNavigation); @@ -521,7 +521,7 @@ public virtual void Detects_missing_foreign_key_for_skip_navigations() orderProductEntity.SetPrimaryKey(new[] { orderProductForeignKey.Properties.Single(), productOrderForeignKey.Properties.Single() }); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, null, true, true); + nameof(Order.Products), null, productEntity, null, true, false); VerifyError( CoreStrings.SkipNavigationNoForeignKey(nameof(Order.Products), nameof(Order)), @@ -544,7 +544,7 @@ public virtual void Detects_missing_inverse_skip_navigations() orderProductEntity.SetPrimaryKey(new[] { orderProductForeignKey.Properties.Single(), productOrderForeignKey.Properties.Single() }); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); VerifyError( CoreStrings.SkipNavigationNoInverse(nameof(Order.Products), nameof(Order)), diff --git a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs index 190aaf53540..64a9841f586 100644 --- a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs @@ -1676,7 +1676,7 @@ public void ProcessNavigationAdded( if (_terminate) { - if (navigation.IsDependentToPrincipal()) + if (navigation.IsOnDependent) { relationshipBuilder.Metadata.HasDependentToPrincipal((string)null); } @@ -1921,7 +1921,7 @@ public void OnSkipNavigationAdded_calls_conventions_in_order(bool useBuilder, bo else { var result = firstEntityBuilder.Metadata.AddSkipNavigation( - nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, true, ConfigurationSource.Convention); + nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, false, ConfigurationSource.Convention); Assert.Equal(!useScope, result == null); } @@ -1991,7 +1991,7 @@ public void OnSkipNavigationAnnotationChanged_calls_conventions_in_order(bool us .IsUnique(false, ConfigurationSource.Convention) .Metadata; var navigation = firstEntityBuilder.Metadata.AddSkipNavigation( - nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, true, ConfigurationSource.Convention); + nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, false, ConfigurationSource.Convention); var scope = useScope ? builder.Metadata.ConventionDispatcher.DelayConventions() : null; @@ -2100,7 +2100,7 @@ public void OnSkipNavigationForeignKeyChanged_calls_conventions_in_order(bool us .IsUnique(false, ConfigurationSource.Convention) .Metadata; var navigation = firstEntityBuilder.Metadata.AddSkipNavigation( - nameof(Order.Products), null, secondEntityBuilder.Metadata, null, true, true, ConfigurationSource.Convention); + nameof(Order.Products), null, secondEntityBuilder.Metadata, null, true, false, ConfigurationSource.Convention); var scope = useScope ? builder.Metadata.ConventionDispatcher.DelayConventions() : null; @@ -2200,7 +2200,7 @@ public void OnSkipNavigationInverseChanged_calls_conventions_in_order(bool useBu .IsUnique(false, ConfigurationSource.Convention) .Metadata; var navigation = firstEntityBuilder.Metadata.AddSkipNavigation( - nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, true, ConfigurationSource.Convention); + nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, false, ConfigurationSource.Convention); var scope = useScope ? builder.Metadata.ConventionDispatcher.DelayConventions() : null; @@ -2211,7 +2211,7 @@ public void OnSkipNavigationInverseChanged_calls_conventions_in_order(bool useBu else { var inverse = secondEntityBuilder.Metadata.AddSkipNavigation( - nameof(Product.Orders), null, firstEntityBuilder.Metadata, secondFk, true, true, ConfigurationSource.Convention); + nameof(Product.Orders), null, firstEntityBuilder.Metadata, secondFk, true, false, ConfigurationSource.Convention); var result = navigation.SetInverse(inverse, ConfigurationSource.Convention); @@ -2288,7 +2288,7 @@ public void OnSkipNavigationRemoved_calls_conventions_in_order(bool useScope) .IsUnique(false, ConfigurationSource.Convention) .Metadata; var navigation = firstEntityBuilder.Metadata.AddSkipNavigation( - nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, true, ConfigurationSource.Convention); + nameof(Order.Products), null, secondEntityBuilder.Metadata, firstFk, true, false, ConfigurationSource.Convention); var scope = useScope ? builder.Metadata.ConventionDispatcher.DelayConventions() : null; diff --git a/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs index 5e4d512c093..17d2a2e418f 100644 --- a/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/RelationshipDiscoveryConventionTest.cs @@ -1052,7 +1052,7 @@ private static void VerifyRelationship( Navigation navigation, string expectedInverseName, bool unique, bool singleRelationship = true) { IForeignKey fk = navigation.ForeignKey; - Assert.Equal(expectedInverseName, navigation.FindInverse()?.Name); + Assert.Equal(expectedInverseName, navigation.Inverse?.Name); Assert.Equal(unique, fk.IsUnique); Assert.NotSame(fk.Properties.Single(), fk.PrincipalKey.Properties.Single()); Assert.NotEqual(fk.PrincipalToDependent?.Name, fk.DependentToPrincipal?.Name); @@ -1064,7 +1064,7 @@ private static void VerifyRelationship( Assert.Single(principalEntityType.GetKeys()); Assert.Empty(principalEntityType.GetDeclaredForeignKeys()); if ((expectedInverseName == null) - && navigation.IsDependentToPrincipal()) + && navigation.IsOnDependent) { Assert.Empty(principalEntityType.GetNavigations()); } @@ -1073,7 +1073,7 @@ private static void VerifyRelationship( Assert.Single(dependentEntityType.GetDeclaredProperties()); Assert.Equal(principalEntityType.IsAssignableFrom(dependentEntityType) ? 1 : 0, dependentEntityType.GetKeys().Count()); if ((expectedInverseName == null) - && !navigation.IsDependentToPrincipal()) + && !navigation.IsOnDependent) { Assert.Empty(dependentEntityType.GetNavigations()); } @@ -1085,7 +1085,7 @@ private static void VerifySelfRef( { IForeignKey fk = navigation.ForeignKey; Assert.Single(fk.DeclaringEntityType.Model.GetEntityTypes()); - Assert.Equal(expectedInverseName, navigation.FindInverse()?.Name); + Assert.Equal(expectedInverseName, navigation.Inverse?.Name); Assert.Equal(unique, fk.IsUnique); Assert.NotSame(fk.Properties.Single(), fk.PrincipalKey.Properties.Single()); Assert.NotEqual(fk.PrincipalToDependent?.Name, fk.DependentToPrincipal?.Name); diff --git a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs index 335731d47d2..a16cea0b933 100644 --- a/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/EntityTypeTest.cs @@ -820,7 +820,7 @@ public void Removing_a_foreign_key_throws_if_referenced_from_skip_navigation() .AddForeignKey(new[] { orderIdProperty }, firstKey, firstEntity); var navigation = firstEntity.AddSkipNavigation( - nameof(Order.Products), null, secondEntity, foreignKey, true, true); + nameof(Order.Products), null, secondEntity, foreignKey, true, false); Assert.Equal(CoreStrings.ForeignKeyInUseSkipNavigation( "{'" + nameof(OrderProduct.OrderId) + "'}", nameof(OrderProduct), nameof(Order.Products), nameof(Order)), @@ -870,17 +870,17 @@ public void Can_add_and_remove_navigations() Assert.Equal(nameof(Order.Customer), customerNavigation.Name); Assert.Same(orderType, customerNavigation.DeclaringEntityType); Assert.Same(customerForeignKey, customerNavigation.ForeignKey); - Assert.True(customerNavigation.IsDependentToPrincipal()); - Assert.False(customerNavigation.IsCollection()); - Assert.Same(customerType, customerNavigation.GetTargetType()); + Assert.True(customerNavigation.IsOnDependent); + Assert.False(customerNavigation.IsCollection); + Assert.Same(customerType, customerNavigation.TargetEntityType); Assert.Same(customerNavigation, customerForeignKey.DependentToPrincipal); Assert.Equal(nameof(Customer.Orders), ordersNavigation.Name); Assert.Same(customerType, ordersNavigation.DeclaringEntityType); Assert.Same(customerForeignKey, ordersNavigation.ForeignKey); - Assert.False(ordersNavigation.IsDependentToPrincipal()); - Assert.True(ordersNavigation.IsCollection()); - Assert.Same(orderType, ordersNavigation.GetTargetType()); + Assert.False(ordersNavigation.IsOnDependent); + Assert.True(ordersNavigation.IsCollection); + Assert.Same(orderType, ordersNavigation.TargetEntityType); Assert.Same(ordersNavigation, customerForeignKey.PrincipalToDependent); Assert.Same(customerNavigation, orderType.GetNavigations().Single()); @@ -912,12 +912,12 @@ public void Can_add_new_navigations_or_get_existing_navigations() Assert.Equal(nameof(Order.Customer), customerNavigation.Name); Assert.Same(orderType, customerNavigation.DeclaringEntityType); Assert.Same(customerForeignKey, customerNavigation.ForeignKey); - Assert.True(customerNavigation.IsDependentToPrincipal()); - Assert.False(customerNavigation.IsCollection()); - Assert.Same(customerType, customerNavigation.GetTargetType()); + Assert.True(customerNavigation.IsOnDependent); + Assert.False(customerNavigation.IsCollection); + Assert.Same(customerType, customerNavigation.TargetEntityType); Assert.Same(customerNavigation, orderType.FindNavigation(nameof(Order.Customer))); - Assert.True(customerNavigation.IsDependentToPrincipal()); + Assert.True(customerNavigation.IsOnDependent); } [ConditionalFact] @@ -1062,9 +1062,9 @@ public void Collection_navigation_properties_can_be_IEnumerables_of_base_target_ Assert.Equal(nameof(Customer.Orders), ordersNavigation.Name); Assert.Same(customerType, ordersNavigation.DeclaringEntityType); Assert.Same(customerForeignKey, ordersNavigation.ForeignKey); - Assert.False(ordersNavigation.IsDependentToPrincipal()); - Assert.True(ordersNavigation.IsCollection()); - Assert.Same(orderType, ordersNavigation.GetTargetType()); + Assert.False(ordersNavigation.IsOnDependent); + Assert.True(ordersNavigation.IsCollection); + Assert.Same(orderType, ordersNavigation.TargetEntityType); Assert.Same(ordersNavigation, customerForeignKey.PrincipalToDependent); } @@ -1120,9 +1120,9 @@ public void Reference_navigation_properties_can_be_of_base_type() Assert.Equal("Customer", customerNavigation.Name); Assert.Same(orderType, customerNavigation.DeclaringEntityType); Assert.Same(customerForeignKey, customerNavigation.ForeignKey); - Assert.True(customerNavigation.IsDependentToPrincipal()); - Assert.False(customerNavigation.IsCollection()); - Assert.Same(customerType, customerNavigation.GetTargetType()); + Assert.True(customerNavigation.IsOnDependent); + Assert.False(customerNavigation.IsCollection); + Assert.Same(customerType, customerNavigation.TargetEntityType); } [ConditionalFact] @@ -1197,7 +1197,9 @@ public void Can_add_and_remove_skip_navigation() var customerForeignKey = orderEntity .AddForeignKey(customerFkProperty, customerKey, customerEntity); var relatedNavigation = orderEntity.AddSkipNavigation( - nameof(Order.RelatedOrder), null, orderEntity, customerForeignKey, false, false); + nameof(Order.RelatedOrder), null, orderEntity, customerForeignKey, false, true); + + Assert.True(relatedNavigation.IsOnDependent); var productEntity = model.AddEntityType(typeof(Product)); var orderProductEntity = model.AddEntityType(typeof(OrderProduct)); @@ -1206,7 +1208,7 @@ public void Can_add_and_remove_skip_navigation() .AddForeignKey(new[] { orderProductFkProperty }, orderKey, orderEntity); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); Assert.Equal(new[] { productsNavigation, relatedNavigation }, orderEntity.GetSkipNavigations()); Assert.Empty(customerEntity.GetSkipNavigations()); @@ -1233,13 +1235,13 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_another_skip_ .AddForeignKey(new[] { orderProductFkProperty }, orderKey, orderEntity); var navigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); Assert.Equal( CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name), Assert.Throws(() => orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1264,7 +1266,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_navigation_ CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name), Assert.Throws(() => orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1286,7 +1288,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_property_th CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name), Assert.Throws(() => orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1308,7 +1310,7 @@ public void Adding_skip_navigation_with_a_name_that_conflicts_with_a_service_pro CoreStrings.ConflictingPropertyOrNavigation(nameof(Order.Products), typeof(Order).Name, typeof(Order).Name), Assert.Throws(() => orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1328,7 +1330,7 @@ public void Adding_CLR_skip_navigation_to_shadow_entity_type_throws() CoreStrings.ClrPropertyOnShadowEntity(nameof(Order.Products), nameof(Order)), Assert.Throws( () => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1348,7 +1350,7 @@ public void Adding_CLR_skip_navigation_targetting_a_shadow_entity_type_throws() CoreStrings.NavigationToShadowEntity(nameof(Order.Products), nameof(Order), nameof(Product)), Assert.Throws( () => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1368,7 +1370,7 @@ public void Adding_CLR_skip_navigation_to_a_mismatched_entity_type_throws() CoreStrings.NoClrNavigation(nameof(Order.Products), nameof(Product)), Assert.Throws( () => productEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1388,7 +1390,7 @@ public void Adding_CLR_collection_skip_navigation_with_mismatched_target_entity_ CoreStrings.NavigationCollectionWrongClrType(nameof(Order.Products), nameof(Order), "ICollection", nameof(Order)), Assert.Throws( () => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, orderEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), Order.ProductsProperty, orderEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1408,7 +1410,7 @@ public void Adding_CLR_reference_skip_navigation_with_mismatched_target_entity_t CoreStrings.NavigationSingleWrongClrType(nameof(Order.Products), nameof(Order), "ICollection", nameof(Order)), Assert.Throws( () => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, orderEntity, orderProductForeignKey, false, true)).Message); + nameof(Order.Products), Order.ProductsProperty, orderEntity, orderProductForeignKey, false, false)).Message); } [ConditionalFact] @@ -1428,7 +1430,7 @@ public void Adding_skip_navigation_with_a_mismatched_memberinfo_throws() CoreStrings.PropertyWrongName(nameof(Order.Products), typeof(Order).Name, nameof(Order.RelatedOrder)), Assert.Throws(() => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.RelatedOrderProperty, productEntity, orderProductForeignKey, true, true)).Message); + nameof(Order.Products), Order.RelatedOrderProperty, productEntity, orderProductForeignKey, true, false)).Message); } [ConditionalFact] @@ -1448,7 +1450,7 @@ public void Adding_dependent_skip_navigation_with_mismatched_foreign_key_throws( nameof(Order.Products), nameof(Order), nameof(OrderProduct), "{'" + nameof(OrderProduct.OrderId) + "'}"), Assert.Throws( () => orderEntity.AddSkipNavigation( - nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, false)).Message); + nameof(Order.Products), Order.ProductsProperty, productEntity, orderProductForeignKey, true, true)).Message); } [ConditionalFact] @@ -1468,7 +1470,7 @@ public void Adding_principal_skip_navigation_with_mismatched_foreign_key_throws( nameof(OrderProduct.Order), nameof(OrderProduct), nameof(Order), "{'" + nameof(OrderProduct.OrderId) + "'}"), Assert.Throws( () => orderProductEntity.AddSkipNavigation( - nameof(OrderProduct.Order), null, orderEntity, orderProductForeignKey, false, true)).Message); + nameof(OrderProduct.Order), null, orderEntity, orderProductForeignKey, false, false)).Message); } [ConditionalFact] diff --git a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs index 33e4afc807b..0961ef66e21 100644 --- a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs @@ -2336,7 +2336,7 @@ public void Can_merge_with_intrahierarchical_relationship_of_higher_source() var baseNavigation = baseEntityBuilder.Metadata.GetNavigations().Single(); Assert.Equal(nameof(Customer.SpecialCustomer), baseNavigation.Name); - Assert.Equal(nameof(SpecialCustomer.Customer), baseNavigation.FindInverse()?.Name); + Assert.Equal(nameof(SpecialCustomer.Customer), baseNavigation.Inverse?.Name); } [ConditionalFact] diff --git a/test/EFCore.Tests/Metadata/Internal/SkipNavigationTest.cs b/test/EFCore.Tests/Metadata/Internal/SkipNavigationTest.cs index 9cc0415eb54..c16486f9b30 100644 --- a/test/EFCore.Tests/Metadata/Internal/SkipNavigationTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/SkipNavigationTest.cs @@ -25,10 +25,10 @@ public void Gets_expected_default_values() .AddForeignKey(new[] { orderIdProperty }, firstKey, firstEntity); var navigation = firstEntity.AddSkipNavigation( - nameof(Order.Products), null, secondEntity, firstFk, true, true); + nameof(Order.Products), null, secondEntity, firstFk, true, false); Assert.True(navigation.IsCollection); - Assert.True(navigation.IsOnPrincipal); + Assert.False(navigation.IsOnDependent); Assert.False(navigation.IsEagerLoaded); Assert.Null(navigation.Inverse); Assert.Equal(firstFk, navigation.ForeignKey); @@ -53,7 +53,7 @@ public void Can_set_foreign_key() var firstFk = associationEntityBuilder .AddForeignKey(new[] { orderIdProperty }, firstKey, firstEntity); - var navigation = firstEntity.AddSkipNavigation(nameof(Order.Products), null, secondEntity, null, true, true); + var navigation = firstEntity.AddSkipNavigation(nameof(Order.Products), null, secondEntity, null, true, false); Assert.Null(navigation.ForeignKey); Assert.Null(navigation.GetForeignKeyConfigurationSource()); @@ -83,7 +83,7 @@ public void Setting_foreign_key_to_skip_navigation_with_wrong_dependent_throws() var orderProductForeignKey = orderProductEntity.AddForeignKey(orderProductFkProperty, orderKey, orderEntity); var navigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, null, true, false); + nameof(Order.Products), null, productEntity, null, true, true); Assert.Equal( CoreStrings.SkipNavigationForeignKeyWrongDependentType( @@ -104,7 +104,7 @@ public void Setting_foreign_key_to_skip_navigation_with_wrong_principal_throws() var orderProductForeignKey = orderProductEntity.AddForeignKey(orderProductFkProperty, orderKey, orderEntity); var navigation = orderProductEntity.AddSkipNavigation( - nameof(OrderProduct.Order), null, orderEntity, null, false, true); + nameof(OrderProduct.Order), null, orderEntity, null, false, false); Assert.Equal( CoreStrings.SkipNavigationForeignKeyWrongPrincipalType( @@ -131,10 +131,10 @@ public void Setting_foreign_key_with_wrong_inverse_throws() .AddForeignKey(new[] { productFkProperty }, productKey, productEntity); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, null, true, true); + nameof(Order.Products), null, productEntity, null, true, false); var ordersNavigation = productEntity.AddSkipNavigation( - nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, true); + nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, false); productsNavigation.SetInverse(ordersNavigation); @@ -164,10 +164,10 @@ public void Can_set_inverse() .AddForeignKey(new[] { productOrderFkProperty }, productKey, productEntity); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); var ordersNavigation = productEntity.AddSkipNavigation( - nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, true); + nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, false); productsNavigation.SetInverse(ordersNavigation); ordersNavigation.SetInverse(productsNavigation); @@ -205,10 +205,10 @@ public void Setting_inverse_targetting_wrong_type_throws() .AddForeignKey(new[] { productOrderFkProperty }, productKey, productEntity); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); var ordersNavigation = orderProductEntity.AddSkipNavigation( - nameof(OrderProduct.Product), null, productEntity, productOrderForeignKey, false, false); + nameof(OrderProduct.Product), null, productEntity, productOrderForeignKey, false, true); Assert.Equal(CoreStrings.SkipNavigationWrongInverse( nameof(OrderProduct.Product), nameof(OrderProduct), nameof(Order.Products), nameof(Product)), @@ -234,10 +234,10 @@ public void Setting_inverse_with_wrong_association_type_throws() .AddForeignKey(new[] { productFkProperty }, productKey, productEntity); var productsNavigation = orderEntity.AddSkipNavigation( - nameof(Order.Products), null, productEntity, orderProductForeignKey, true, true); + nameof(Order.Products), null, productEntity, orderProductForeignKey, true, false); var ordersNavigation = productEntity.AddSkipNavigation( - nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, true); + nameof(Product.Orders), null, orderEntity, productOrderForeignKey, true, false); Assert.Equal(CoreStrings.SkipInverseMismatchedAssociationType( nameof(Product.Orders), nameof(Product), nameof(Order.Products), nameof(OrderProduct)), diff --git a/test/EFCore.Tests/Metadata/NavigationExtensionsTest.cs b/test/EFCore.Tests/Metadata/NavigationExtensionsTest.cs index 354037251a2..8de504727f2 100644 --- a/test/EFCore.Tests/Metadata/NavigationExtensionsTest.cs +++ b/test/EFCore.Tests/Metadata/NavigationExtensionsTest.cs @@ -19,8 +19,8 @@ public void Can_get_one_to_many_inverses() var category = model.FindEntityType(typeof(Product)).GetNavigations().Single(e => e.Name == "Category"); var products = model.FindEntityType(typeof(Category)).GetNavigations().Single(e => e.Name == "Products"); - Assert.Same(category, products.FindInverse()); - Assert.Same(products, category.FindInverse()); + Assert.Same(category, products.Inverse); + Assert.Same(products, category.Inverse); } [ConditionalFact] @@ -31,8 +31,8 @@ public void Can_get_one_to_one_inverses() var category = model.FindEntityType(typeof(Product)).GetNavigations().Single(e => e.Name == "FeaturedProductCategory"); var product = model.FindEntityType(typeof(Category)).GetNavigations().Single(e => e.Name == "FeaturedProduct"); - Assert.Same(category, product.FindInverse()); - Assert.Same(product, category.FindInverse()); + Assert.Same(category, product.Inverse); + Assert.Same(product, category.Inverse); } [ConditionalFact] @@ -46,8 +46,8 @@ public void Can_get_target_ends() var category = productType.GetNavigations().Single(e => e.Name == "Category"); var products = categoryType.GetNavigations().Single(e => e.Name == "Products"); - Assert.Same(productType, products.GetTargetType()); - Assert.Same(categoryType, category.GetTargetType()); + Assert.Same(productType, products.TargetEntityType); + Assert.Same(categoryType, category.TargetEntityType); } [ConditionalFact] @@ -56,22 +56,22 @@ public void Returns_null_when_no_inverse() var products = BuildModel(createCategory: false).FindEntityType(typeof(Category)).GetNavigations() .Single(e => e.Name == "Products"); - Assert.Null(products.FindInverse()); + Assert.Null(products.Inverse); var category = BuildModel(createProducts: false).FindEntityType(typeof(Product)).GetNavigations() .Single(e => e.Name == "Category"); - Assert.Null(category.FindInverse()); + Assert.Null(category.Inverse); var featuredCategory = BuildModel(createFeaturedProduct: false).FindEntityType(typeof(Product)).GetNavigations() .Single(e => e.Name == "FeaturedProductCategory"); - Assert.Null(featuredCategory.FindInverse()); + Assert.Null(featuredCategory.Inverse); var featuredProduct = BuildModel(createFeaturedProductCategory: false).FindEntityType(typeof(Category)).GetNavigations() .Single(e => e.Name == "FeaturedProduct"); - Assert.Null(featuredProduct.FindInverse()); + Assert.Null(featuredProduct.Inverse); } private class Category diff --git a/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs b/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs index 7b4e2669a04..b6341cb59d9 100644 --- a/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs @@ -373,7 +373,7 @@ public virtual void Pulling_relationship_to_a_derived_type_one_to_one_creates_re .WithOne(e => e.SpecialOrderCombination) .HasPrincipalKey(e => e.Id); - Assert.Null(dependentEntityBuilder.Metadata.GetNavigations().Single().FindInverse()); + Assert.Null(dependentEntityBuilder.Metadata.GetNavigations().Single().Inverse); var newFk = derivedDependentEntityBuilder.Metadata.GetDeclaredNavigations().Single().ForeignKey; Assert.Equal(nameof(SpecialOrder.SpecialOrderCombination), newFk.DependentToPrincipal.Name); Assert.Equal(nameof(OrderCombination.Order), newFk.PrincipalToDependent.Name); @@ -400,7 +400,7 @@ public virtual void Pulling_relationship_to_a_derived_type_one_to_one_with_fk_cr .WithOne() .HasForeignKey(e => e.SpecialCustomerId); - Assert.Null(dependentEntityBuilder.Metadata.GetNavigations().Single().FindInverse()); + Assert.Null(dependentEntityBuilder.Metadata.GetNavigations().Single().Inverse); var newFk = principalEntityBuilder.Metadata.GetDeclaredNavigations().Single().ForeignKey; Assert.Null(newFk.DependentToPrincipal); Assert.Equal(nameof(OrderCombination.Order), newFk.PrincipalToDependent.Name); @@ -725,11 +725,11 @@ public virtual void Relationships_are_discovered_on_the_base_entity_type() var bookLabel = modelBuilder.Model.FindEntityType(typeof(BookLabel)); var specialNavigation = bookLabel.GetDeclaredNavigations().Single(n => n.Name == nameof(BookLabel.SpecialBookLabel)); - Assert.Equal(typeof(SpecialBookLabel), specialNavigation.GetTargetType().ClrType); - Assert.Equal(nameof(SpecialBookLabel.BookLabel), specialNavigation.FindInverse().Name); + Assert.Equal(typeof(SpecialBookLabel), specialNavigation.TargetEntityType.ClrType); + Assert.Equal(nameof(SpecialBookLabel.BookLabel), specialNavigation.Inverse.Name); var anotherNavigation = bookLabel.GetDeclaredNavigations().Single(n => n.Name == nameof(BookLabel.AnotherBookLabel)); - Assert.Equal(typeof(AnotherBookLabel), anotherNavigation.GetTargetType().ClrType); - Assert.Null(anotherNavigation.FindInverse()); + Assert.Equal(typeof(AnotherBookLabel), anotherNavigation.TargetEntityType.ClrType); + Assert.Null(anotherNavigation.Inverse); } [ConditionalFact] @@ -763,15 +763,15 @@ public virtual void Relationships_on_derived_types_are_discovered_first_if_base_ var citizen = modelBuilder.Model.FindEntityType(typeof(CitizenViewModel)); var citizenNavigation = citizen.GetDeclaredNavigations().Single(n => n.Name == nameof(CitizenViewModel.CityVM)); - Assert.Equal(nameof(CityViewModel.People), citizenNavigation.FindInverse().Name); + Assert.Equal(nameof(CityViewModel.People), citizenNavigation.Inverse.Name); var doctor = modelBuilder.Model.FindEntityType(typeof(DoctorViewModel)); var doctorNavigation = doctor.GetDeclaredNavigations().Single(n => n.Name == nameof(CitizenViewModel.CityVM)); - Assert.Equal(nameof(CityViewModel.Medics), doctorNavigation.FindInverse().Name); + Assert.Equal(nameof(CityViewModel.Medics), doctorNavigation.Inverse.Name); var police = modelBuilder.Model.FindEntityType(typeof(PoliceViewModel)); var policeNavigation = police.GetDeclaredNavigations().Single(n => n.Name == nameof(CitizenViewModel.CityVM)); - Assert.Equal(nameof(CityViewModel.Police), policeNavigation.FindInverse().Name); + Assert.Equal(nameof(CityViewModel.Police), policeNavigation.Inverse.Name); Assert.Empty(modelBuilder.Model.FindEntityType(typeof(CityViewModel)).GetForeignKeys()); diff --git a/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs b/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs index 8082fe00d4b..c141ad541c7 100644 --- a/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs @@ -1662,7 +1662,7 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ var existingFk = navigation.ForeignKey; Assert.Same(existingFk, principalType.GetNavigations().Single().ForeignKey); Assert.Equal(nameof(ToastedBun.Whoopper), navigation.Name); - Assert.Equal(nameof(Whoopper.ToastedBun), navigation.FindInverse().Name); + Assert.Equal(nameof(Whoopper.ToastedBun), navigation.Inverse.Name); Assert.Equal(existingFk.DeclaringEntityType == dependentType ? 0 : 1, principalType.GetForeignKeys().Count()); Assert.Equal(2, principalType.GetKeys().Count()); Assert.Same(dependentKey, dependentType.GetKeys().Single()); diff --git a/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs b/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs index b1ef52998ed..6ebcc7ca926 100644 --- a/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs @@ -1887,7 +1887,7 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ var existingFk = navigation.ForeignKey; Assert.Same(existingFk, principalType.GetNavigations().Single().ForeignKey); Assert.Equal(nameof(ToastedBun.Whoopper), navigation.Name); - Assert.Equal(nameof(Whoopper.ToastedBun), navigation.FindInverse().Name); + Assert.Equal(nameof(Whoopper.ToastedBun), navigation.Inverse.Name); Assert.Equal(existingFk.DeclaringEntityType == dependentType ? 0 : 1, principalType.GetForeignKeys().Count()); Assert.Equal(2, principalType.GetKeys().Count()); Assert.Same(dependentKey, dependentType.GetKeys().Single()); diff --git a/test/EFCore.Tests/ModelBuilding/OwnedTypesTestBase.cs b/test/EFCore.Tests/ModelBuilding/OwnedTypesTestBase.cs index ee3406d0237..3dc571951cc 100644 --- a/test/EFCore.Tests/ModelBuilding/OwnedTypesTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/OwnedTypesTestBase.cs @@ -804,7 +804,7 @@ public virtual void Can_map_derived_of_owned_type() var navigationsToDerived = model.GetEntityTypes().SelectMany(e => e.GetDeclaredNavigations()).Where( n => { - var targetType = n.GetTargetType().ClrType; + var targetType = n.TargetEntityType.ClrType; return targetType != typeof(DetailsBase) && typeof(DetailsBase).IsAssignableFrom(targetType); }); Assert.Empty(navigationsToDerived); @@ -832,7 +832,7 @@ public virtual void Can_map_derived_of_owned_type_first() model.GetEntityTypes().SelectMany(e => e.GetDeclaredNavigations()).Where( n => { - var targetType = n.GetTargetType().ClrType; + var targetType = n.TargetEntityType.ClrType; return targetType != typeof(DetailsBase) && typeof(DetailsBase).IsAssignableFrom(targetType); })); Assert.Single(owned.GetForeignKeys());