diff --git a/src/EFCore/ChangeTracking/CollectionEntry.cs b/src/EFCore/ChangeTracking/CollectionEntry.cs
index fca28718d67..031dae40023 100644
--- a/src/EFCore/ChangeTracking/CollectionEntry.cs
+++ b/src/EFCore/ChangeTracking/CollectionEntry.cs
@@ -283,7 +283,7 @@ protected virtual InternalEntityEntry GetInternalTargetEntry([NotNull] object en
: InternalEntry.StateManager.GetOrCreateEntry(entity, Metadata.TargetEntityType);
private ICollectionLoader TargetLoader
- => _loader ??= Metadata is ISkipNavigation skipNavigation
+ => _loader ??= Metadata is IRuntimeSkipNavigation skipNavigation
? skipNavigation.GetManyToManyLoader()
: new EntityFinderCollectionLoaderAdapter(
InternalEntry.StateManager.CreateEntityFinder(Metadata.TargetEntityType),
diff --git a/src/EFCore/Extensions/ConventionNavigationExtensions.cs b/src/EFCore/Extensions/ConventionNavigationExtensions.cs
index f8e1d46195e..677582fc688 100644
--- a/src/EFCore/Extensions/ConventionNavigationExtensions.cs
+++ b/src/EFCore/Extensions/ConventionNavigationExtensions.cs
@@ -13,6 +13,7 @@ namespace Microsoft.EntityFrameworkCore
///
/// Extension methods for .
///
+ [Obsolete("Use IConventionNavigation")]
public static class ConventionNavigationExtensions
{
///
diff --git a/src/EFCore/Extensions/IndexExtensions.cs b/src/EFCore/Extensions/IndexExtensions.cs
index 07cb4af6da6..6c20e738123 100644
--- a/src/EFCore/Extensions/IndexExtensions.cs
+++ b/src/EFCore/Extensions/IndexExtensions.cs
@@ -19,72 +19,5 @@ namespace Microsoft.EntityFrameworkCore
///
public static class IndexExtensions
{
- ///
- ///
- /// Gets a factory for key values based on the index key values taken from various forms of entity data.
- ///
- ///
- /// This method is typically used by database providers (and other extensions). It is generally
- /// not used in application code.
- ///
- ///
- /// The index metadata.
- /// The type of the index instance.
- /// The factory.
- public static IDependentKeyValueFactory GetNullableValueFactory([NotNull] this IReadOnlyIndex index)
- => index.AsIndex().GetNullableValueFactory();
-
- ///
- ///
- /// Creates a human-readable representation of the given metadata.
- ///
- ///
- /// Warning: Do not rely on the format of the returned string.
- /// It is designed for debugging only and may change arbitrarily between releases.
- ///
- ///
- /// The metadata item.
- /// Options for generating the string.
- /// The number of indent spaces to use before each new line.
- /// A human-readable representation.
- public static string ToDebugString(
- [NotNull] this IReadOnlyIndex index,
- MetadataDebugStringOptions options,
- int indent = 0)
- {
- var builder = new StringBuilder();
- var indentString = new string(' ', indent);
-
- builder.Append(indentString);
-
- var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
- if (singleLine)
- {
- builder.Append("Index: ");
- }
-
- builder
- .AppendJoin(
- ", ",
- index.Properties.Select(
- p => singleLine
- ? p.DeclaringEntityType.DisplayName() + "." + p.Name
- : p.Name));
-
- builder.Append(" " + index.Name ?? "");
-
- if (index.IsUnique)
- {
- builder.Append(" Unique");
- }
-
- if (!singleLine
- && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
- {
- builder.Append(index.AnnotationsToDebugString(indent + 2));
- }
-
- return builder.ToString();
- }
}
}
diff --git a/src/EFCore/Extensions/MutableNavigationExtensions.cs b/src/EFCore/Extensions/MutableNavigationExtensions.cs
index f1d25fb7806..c707b21b1ca 100644
--- a/src/EFCore/Extensions/MutableNavigationExtensions.cs
+++ b/src/EFCore/Extensions/MutableNavigationExtensions.cs
@@ -13,6 +13,7 @@ namespace Microsoft.EntityFrameworkCore
///
/// Extension methods for .
///
+ [Obsolete("Use IMutableNavigation")]
public static class MutableNavigationExtensions
{
///
diff --git a/src/EFCore/Extensions/NavigationExtensions.cs b/src/EFCore/Extensions/NavigationExtensions.cs
index c3bfe1fd178..188e2751fe1 100644
--- a/src/EFCore/Extensions/NavigationExtensions.cs
+++ b/src/EFCore/Extensions/NavigationExtensions.cs
@@ -3,11 +3,8 @@
using System;
using System.Diagnostics;
-using System.Text;
using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
#nullable enable
@@ -18,6 +15,7 @@ namespace Microsoft.EntityFrameworkCore
///
/// Extension methods for .
///
+ [Obsolete("Use IReadOnlyNavigation")]
public static class NavigationExtensions
{
///
@@ -30,7 +28,7 @@ public static class NavigationExtensions
/// type that points to the principal entity, otherwise .
///
[DebuggerStepThrough]
- [Obsolete("Use INavigation.IsOnDependent")]
+ [Obsolete("Use IReadOnlyNavigation.IsOnDependent")]
public static bool IsDependentToPrincipal([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsOnDependent;
@@ -42,7 +40,7 @@ public static bool IsDependentToPrincipal([NotNull] this IReadOnlyNavigation nav
/// if this is a collection property, false if it is a reference property.
///
[DebuggerStepThrough]
- [Obsolete("Use INavigation.IsCollection")]
+ [Obsolete("Use IReadOnlyNavigation.IsCollection")]
public static bool IsCollection([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsCollection;
@@ -55,7 +53,7 @@ public static bool IsCollection([NotNull] this IReadOnlyNavigation navigation)
/// The inverse navigation, or if none is defined.
///
[DebuggerStepThrough]
- [Obsolete("Use INavigation.Inverse")]
+ [Obsolete("Use IReadOnlyNavigation.Inverse")]
public static IReadOnlyNavigation? FindInverse([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).Inverse;
@@ -66,7 +64,7 @@ public static bool IsCollection([NotNull] this IReadOnlyNavigation navigation)
/// The navigation property to find the target entity type of.
/// The target entity type.
[DebuggerStepThrough]
- [Obsolete("Use INavigation.TargetEntityType")]
+ [Obsolete("Use IReadOnlyNavigation.TargetEntityType")]
public static IReadOnlyEntityType GetTargetType([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).TargetEntityType;
@@ -75,93 +73,8 @@ public static IReadOnlyEntityType GetTargetType([NotNull] this IReadOnlyNavigati
///
/// 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")]
+ [Obsolete("Use IReadOnlyNavigation.IsEagerLoaded")]
public static bool IsEagerLoaded([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsEagerLoaded;
-
- ///
- ///
- /// Creates a human-readable representation of the given metadata.
- ///
- ///
- /// Warning: Do not rely on the format of the returned string.
- /// It is designed for debugging only and may change arbitrarily between releases.
- ///
- ///
- /// The metadata item.
- /// Options for generating the string.
- /// The number of indent spaces to use before each new line.
- /// A human-readable representation.
- public static string ToDebugString(
- [NotNull] this IReadOnlyNavigation navigation,
- MetadataDebugStringOptions options,
- int indent = 0)
- {
- var builder = new StringBuilder();
- var indentString = new string(' ', indent);
-
- builder.Append(indentString);
-
- var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
- if (singleLine)
- {
- builder.Append($"Navigation: {navigation.DeclaringEntityType.DisplayName()}.");
- }
-
- builder.Append(navigation.Name);
-
- var field = navigation.GetFieldName();
- if (field == null)
- {
- builder.Append(" (no field, ");
- }
- else if (!field.EndsWith(">k__BackingField", StringComparison.Ordinal))
- {
- builder.Append($" ({field}, ");
- }
- else
- {
- builder.Append(" (");
- }
-
- builder.Append(navigation.ClrType?.ShortDisplayName()).Append(")");
-
- if (navigation.IsCollection)
- {
- builder.Append(" Collection");
- }
-
- builder.Append(navigation.IsOnDependent ? " ToPrincipal " : " ToDependent ");
-
- builder.Append(navigation.TargetEntityType.DisplayName());
-
- if (navigation.Inverse != null)
- {
- builder.Append(" Inverse: ").Append(navigation.Inverse.Name);
- }
-
- if (navigation.GetPropertyAccessMode() != PropertyAccessMode.PreferField)
- {
- builder.Append(" PropertyAccessMode.").Append(navigation.GetPropertyAccessMode());
- }
-
- if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
- && ((Annotatable)navigation).IsReadOnly)
- {
- var indexes = ((INavigation)navigation).GetPropertyIndexes();
- builder.Append(" ").Append(indexes.Index);
- builder.Append(" ").Append(indexes.OriginalValueIndex);
- builder.Append(" ").Append(indexes.RelationshipIndex);
- builder.Append(" ").Append(indexes.ShadowIndex);
- builder.Append(" ").Append(indexes.StoreGenerationIndex);
- }
-
- if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
- {
- builder.Append(navigation.AnnotationsToDebugString(indent + 2));
- }
-
- return builder.ToString();
- }
}
}
diff --git a/src/EFCore/Extensions/ServicePropertyExtensions.cs b/src/EFCore/Extensions/ServicePropertyExtensions.cs
deleted file mode 100644
index 179bcd5221d..00000000000
--- a/src/EFCore/Extensions/ServicePropertyExtensions.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.Text;
-using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-
-#nullable enable
-
-// ReSharper disable once CheckNamespace
-namespace Microsoft.EntityFrameworkCore
-{
- ///
- /// Extension methods for .
- ///
- public static class ServicePropertyExtensions
- {
- ///
- ///
- /// Creates a human-readable representation of the given metadata.
- ///
- ///
- /// Warning: Do not rely on the format of the returned string.
- /// It is designed for debugging only and may change arbitrarily between releases.
- ///
- ///
- /// The metadata item.
- /// Options for generating the string.
- /// The number of indent spaces to use before each new line.
- /// A human-readable representation.
- public static string ToDebugString(
- [NotNull] this IReadOnlyServiceProperty serviceProperty,
- MetadataDebugStringOptions options,
- int indent = 0)
- {
- var builder = new StringBuilder();
- var indentString = new string(' ', indent);
-
- builder.Append(indentString);
-
- var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
- if (singleLine)
- {
- builder.Append("Service property: ").Append(serviceProperty.DeclaringType.DisplayName()).Append(".");
- }
-
- builder.Append(serviceProperty.Name);
-
- if (serviceProperty.GetFieldName() == null)
- {
- builder.Append(" (no field, ");
- }
- else
- {
- builder.Append(" (").Append(serviceProperty.GetFieldName()).Append(", ");
- }
-
- builder.Append(serviceProperty.ClrType?.ShortDisplayName()).Append(")");
-
- if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
- {
- builder.Append(serviceProperty.AnnotationsToDebugString(indent + 2));
- }
-
- return builder.ToString();
- }
- }
-}
diff --git a/src/EFCore/Extensions/SkipNavigationExtensions.cs b/src/EFCore/Extensions/SkipNavigationExtensions.cs
deleted file mode 100644
index 7655b32917b..00000000000
--- a/src/EFCore/Extensions/SkipNavigationExtensions.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.Text;
-using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
-
-#nullable enable
-
-// ReSharper disable once CheckNamespace
-namespace Microsoft.EntityFrameworkCore
-{
- ///
- /// Extension methods for .
- ///
- public static class SkipNavigationExtensions
- {
- ///
- ///
- /// Creates a human-readable representation of the given metadata.
- ///
- ///
- /// Warning: Do not rely on the format of the returned string.
- /// It is designed for debugging only and may change arbitrarily between releases.
- ///
- ///
- /// The metadata item.
- /// Options for generating the string.
- /// The number of indent spaces to use before each new line.
- /// A human-readable representation.
- public static string ToDebugString(
- [NotNull] this IReadOnlySkipNavigation navigation,
- MetadataDebugStringOptions options,
- int indent = 0)
- {
- var builder = new StringBuilder();
- var indentString = new string(' ', indent);
-
- builder.Append(indentString);
-
- var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
- if (singleLine)
- {
- builder.Append($"SkipNavigation: {navigation.DeclaringEntityType.DisplayName()}.");
- }
-
- builder.Append(navigation.Name);
-
- var field = navigation.GetFieldName();
- if (field == null)
- {
- builder.Append(" (no field, ");
- }
- else if (!field.EndsWith(">k__BackingField", StringComparison.Ordinal))
- {
- builder.Append($" ({field}, ");
- }
- else
- {
- builder.Append(" (");
- }
-
- builder.Append(navigation.ClrType?.ShortDisplayName()).Append(")");
-
- if (navigation.IsCollection)
- {
- builder.Append(" Collection");
- }
-
- builder.Append(navigation.TargetEntityType.DisplayName());
-
- if (navigation.Inverse != null)
- {
- builder.Append(" Inverse: ").Append(navigation.Inverse.Name);
- }
-
- if (navigation.GetPropertyAccessMode() != PropertyAccessMode.PreferField)
- {
- builder.Append(" PropertyAccessMode.").Append(navigation.GetPropertyAccessMode());
- }
-
- if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
- && ((Annotatable)navigation).IsReadOnly)
- {
- var indexes = ((ISkipNavigation)navigation).GetPropertyIndexes();
- builder.Append(" ").Append(indexes.Index);
- builder.Append(" ").Append(indexes.OriginalValueIndex);
- builder.Append(" ").Append(indexes.RelationshipIndex);
- builder.Append(" ").Append(indexes.ShadowIndex);
- builder.Append(" ").Append(indexes.StoreGenerationIndex);
- }
-
- if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
- {
- builder.Append(navigation.AnnotationsToDebugString(indent + 2));
- }
-
- return builder.ToString();
- }
- }
-}
diff --git a/src/EFCore/Metadata/IConventionNavigationBase.cs b/src/EFCore/Metadata/IConventionNavigationBase.cs
index bfb0a14270b..98c832b8445 100644
--- a/src/EFCore/Metadata/IConventionNavigationBase.cs
+++ b/src/EFCore/Metadata/IConventionNavigationBase.cs
@@ -26,7 +26,7 @@ public interface IConventionNavigationBase : IReadOnlyNavigationBase, IConventio
/// The configured value.
bool? SetIsEagerLoaded(bool? eagerLoaded, bool fromDataAnnotation = false)
{
- this.SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, fromDataAnnotation);
+ SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, fromDataAnnotation);
return eagerLoaded;
}
diff --git a/src/EFCore/Metadata/IIndex.cs b/src/EFCore/Metadata/IIndex.cs
index 5bf0739353f..5993a0f8afd 100644
--- a/src/EFCore/Metadata/IIndex.cs
+++ b/src/EFCore/Metadata/IIndex.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Infrastructure;
#nullable enable
@@ -24,5 +25,19 @@ public interface IIndex : IReadOnlyIndex, IAnnotatable
/// may be defined on a base type).
///
new IEntityType DeclaringEntityType { get; }
+
+ ///
+ ///
+ /// Gets a factory for key values based on the index key values taken from various forms of entity data.
+ ///
+ ///
+ /// This method is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// The type of the index instance.
+ /// The factory.
+ IDependentKeyValueFactory GetNullableValueFactory();
+
}
}
diff --git a/src/EFCore/Metadata/IMutableNavigationBase.cs b/src/EFCore/Metadata/IMutableNavigationBase.cs
index 43de45380a2..d3676a21bca 100644
--- a/src/EFCore/Metadata/IMutableNavigationBase.cs
+++ b/src/EFCore/Metadata/IMutableNavigationBase.cs
@@ -23,6 +23,6 @@ public interface IMutableNavigationBase : IReadOnlyNavigationBase, IMutablePrope
///
/// A value indicating whether this navigation should be eager loaded by default.
void SetIsEagerLoaded(bool? eagerLoaded)
- => this.SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded);
+ => SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded);
}
}
diff --git a/src/EFCore/Metadata/INavigationBase.cs b/src/EFCore/Metadata/INavigationBase.cs
index 0c986dcb864..5a0c4f50810 100644
--- a/src/EFCore/Metadata/INavigationBase.cs
+++ b/src/EFCore/Metadata/INavigationBase.cs
@@ -43,6 +43,13 @@ public interface INavigationBase : IReadOnlyNavigationBase, IPropertyBase
get => (INavigationBase?)((IReadOnlyNavigationBase)this).Inverse;
}
+ ///
+ /// Gets the for this navigation property, if it's a collection
+ /// navigation.
+ ///
+ /// The accessor.
+ IClrCollectionAccessor? GetCollectionAccessor();
+
///
/// Calls for a to mark it as loaded
/// when a no-tracking query has eagerly loaded this relationship.
diff --git a/src/EFCore/Metadata/IReadOnlyIndex.cs b/src/EFCore/Metadata/IReadOnlyIndex.cs
index 0c382a2811d..3b65ded1669 100644
--- a/src/EFCore/Metadata/IReadOnlyIndex.cs
+++ b/src/EFCore/Metadata/IReadOnlyIndex.cs
@@ -2,6 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using System.Linq;
+using System.Text;
using Microsoft.EntityFrameworkCore.Infrastructure;
#nullable enable
@@ -34,5 +36,54 @@ public interface IReadOnlyIndex : IReadOnlyAnnotatable
/// may be defined on a base type).
///
IReadOnlyEntityType DeclaringEntityType { get; }
+
+ ///
+ ///
+ /// Creates a human-readable representation of the given metadata.
+ ///
+ ///
+ /// Warning: Do not rely on the format of the returned string.
+ /// It is designed for debugging only and may change arbitrarily between releases.
+ ///
+ ///
+ /// Options for generating the string.
+ /// The number of indent spaces to use before each new line.
+ /// A human-readable representation.
+ string ToDebugString(MetadataDebugStringOptions options, int indent = 0)
+ {
+ var builder = new StringBuilder();
+ var indentString = new string(' ', indent);
+
+ builder.Append(indentString);
+
+ var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
+ if (singleLine)
+ {
+ builder.Append("Index: ");
+ }
+
+ builder
+ .AppendJoin(
+ ", ",
+ Properties.Select(
+ p => singleLine
+ ? p.DeclaringEntityType.DisplayName() + "." + p.Name
+ : p.Name));
+
+ builder.Append(" " + Name ?? "");
+
+ if (IsUnique)
+ {
+ builder.Append(" Unique");
+ }
+
+ if (!singleLine
+ && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
+ {
+ builder.Append(AnnotationsToDebugString(indent + 2));
+ }
+
+ return builder.ToString();
+ }
}
}
diff --git a/src/EFCore/Metadata/IReadOnlyNavigation.cs b/src/EFCore/Metadata/IReadOnlyNavigation.cs
index 762bcce3525..60d274704ad 100644
--- a/src/EFCore/Metadata/IReadOnlyNavigation.cs
+++ b/src/EFCore/Metadata/IReadOnlyNavigation.cs
@@ -1,7 +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 System.Text;
+using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
#nullable enable
@@ -63,15 +66,6 @@ bool IsOnDependent
get => ForeignKey.DependentToPrincipal == this;
}
- ///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
- ///
- /// The accessor.
- [DebuggerStepThrough]
- new IClrCollectionAccessor? GetCollectionAccessor()
- => ((Navigation)this).CollectionAccessor;
-
///
/// Gets the entity type that this navigation property belongs to.
///
@@ -109,12 +103,84 @@ bool IReadOnlyNavigationBase.IsCollection
}
///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
+ ///
+ /// Creates a human-readable representation of the given metadata.
+ ///
+ ///
+ /// Warning: Do not rely on the format of the returned string.
+ /// It is designed for debugging only and may change arbitrarily between releases.
+ ///
///
- /// The accessor.
- [DebuggerStepThrough]
- IClrCollectionAccessor? IReadOnlyNavigationBase.GetCollectionAccessor()
- => GetCollectionAccessor();
+ /// Options for generating the string.
+ /// The number of indent spaces to use before each new line.
+ /// A human-readable representation.
+ string ToDebugString(MetadataDebugStringOptions options, int indent = 0)
+ {
+ var builder = new StringBuilder();
+ var indentString = new string(' ', indent);
+
+ builder.Append(indentString);
+
+ var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
+ if (singleLine)
+ {
+ builder.Append($"Navigation: {DeclaringEntityType.DisplayName()}.");
+ }
+
+ builder.Append(Name);
+
+ var field = GetFieldName();
+ if (field == null)
+ {
+ builder.Append(" (no field, ");
+ }
+ else if (!field.EndsWith(">k__BackingField", StringComparison.Ordinal))
+ {
+ builder.Append($" ({field}, ");
+ }
+ else
+ {
+ builder.Append(" (");
+ }
+
+ builder.Append(ClrType?.ShortDisplayName()).Append(")");
+
+ if (IsCollection)
+ {
+ builder.Append(" Collection");
+ }
+
+ builder.Append(IsOnDependent ? " ToPrincipal " : " ToDependent ");
+
+ builder.Append(TargetEntityType.DisplayName());
+
+ if (Inverse != null)
+ {
+ builder.Append(" Inverse: ").Append(Inverse.Name);
+ }
+
+ if (GetPropertyAccessMode() != PropertyAccessMode.PreferField)
+ {
+ builder.Append(" PropertyAccessMode.").Append(GetPropertyAccessMode());
+ }
+
+ if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
+ && ((Annotatable)this).IsReadOnly)
+ {
+ var indexes = ((INavigation)this).GetPropertyIndexes();
+ builder.Append(" ").Append(indexes.Index);
+ builder.Append(" ").Append(indexes.OriginalValueIndex);
+ builder.Append(" ").Append(indexes.RelationshipIndex);
+ builder.Append(" ").Append(indexes.ShadowIndex);
+ builder.Append(" ").Append(indexes.StoreGenerationIndex);
+ }
+
+ if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
+ {
+ builder.Append(AnnotationsToDebugString(indent + 2));
+ }
+
+ return builder.ToString();
+ }
}
}
diff --git a/src/EFCore/Metadata/IReadOnlyNavigationBase.cs b/src/EFCore/Metadata/IReadOnlyNavigationBase.cs
index df48ee0f5c1..9795e67b8cb 100644
--- a/src/EFCore/Metadata/IReadOnlyNavigationBase.cs
+++ b/src/EFCore/Metadata/IReadOnlyNavigationBase.cs
@@ -37,12 +37,5 @@ public interface IReadOnlyNavigationBase : IReadOnlyPropertyBase
///
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/IReadOnlyServiceProperty.cs b/src/EFCore/Metadata/IReadOnlyServiceProperty.cs
index 2fb7e894d14..7ed115d30dd 100644
--- a/src/EFCore/Metadata/IReadOnlyServiceProperty.cs
+++ b/src/EFCore/Metadata/IReadOnlyServiceProperty.cs
@@ -1,6 +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.Text;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
#nullable enable
namespace Microsoft.EntityFrameworkCore.Metadata
@@ -20,5 +23,51 @@ public interface IReadOnlyServiceProperty : IReadOnlyPropertyBase
/// The for this property.
///
ServiceParameterBinding? ParameterBinding { get; }
+
+ ///
+ ///
+ /// Creates a human-readable representation of the given metadata.
+ ///
+ ///
+ /// Warning: Do not rely on the format of the returned string.
+ /// It is designed for debugging only and may change arbitrarily between releases.
+ ///
+ ///
+ /// Options for generating the string.
+ /// The number of indent spaces to use before each new line.
+ /// A human-readable representation.
+ string ToDebugString(MetadataDebugStringOptions options, int indent = 0)
+ {
+ var builder = new StringBuilder();
+ var indentString = new string(' ', indent);
+
+ builder.Append(indentString);
+
+ var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
+ if (singleLine)
+ {
+ builder.Append("Service property: ").Append(DeclaringType.DisplayName()).Append(".");
+ }
+
+ builder.Append(Name);
+
+ if (GetFieldName() == null)
+ {
+ builder.Append(" (no field, ");
+ }
+ else
+ {
+ builder.Append(" (").Append(GetFieldName()).Append(", ");
+ }
+
+ builder.Append(ClrType?.ShortDisplayName()).Append(")");
+
+ if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
+ {
+ builder.Append(AnnotationsToDebugString(indent + 2));
+ }
+
+ return builder.ToString();
+ }
}
}
diff --git a/src/EFCore/Metadata/IReadOnlySkipNavigation.cs b/src/EFCore/Metadata/IReadOnlySkipNavigation.cs
index c1179d75311..7a960002163 100644
--- a/src/EFCore/Metadata/IReadOnlySkipNavigation.cs
+++ b/src/EFCore/Metadata/IReadOnlySkipNavigation.cs
@@ -1,7 +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 System.Text;
+using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
#nullable enable
@@ -45,11 +48,82 @@ IReadOnlyNavigationBase IReadOnlyNavigationBase.Inverse
bool IsOnDependent { get; }
///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
+ ///
+ /// Creates a human-readable representation of the given metadata.
+ ///
+ ///
+ /// Warning: Do not rely on the format of the returned string.
+ /// It is designed for debugging only and may change arbitrarily between releases.
+ ///
///
- /// The accessor.
- IClrCollectionAccessor? IReadOnlyNavigationBase.GetCollectionAccessor()
- => ((SkipNavigation)this).CollectionAccessor;
+ /// Options for generating the string.
+ /// The number of indent spaces to use before each new line.
+ /// A human-readable representation.
+ string ToDebugString(MetadataDebugStringOptions options, int indent = 0)
+ {
+ var builder = new StringBuilder();
+ var indentString = new string(' ', indent);
+
+ builder.Append(indentString);
+
+ var singleLine = (options & MetadataDebugStringOptions.SingleLine) != 0;
+ if (singleLine)
+ {
+ builder.Append($"SkipNavigation: {DeclaringEntityType.DisplayName()}.");
+ }
+
+ builder.Append(Name);
+
+ var field = GetFieldName();
+ if (field == null)
+ {
+ builder.Append(" (no field, ");
+ }
+ else if (!field.EndsWith(">k__BackingField", StringComparison.Ordinal))
+ {
+ builder.Append($" ({field}, ");
+ }
+ else
+ {
+ builder.Append(" (");
+ }
+
+ builder.Append(ClrType?.ShortDisplayName()).Append(")");
+
+ if (IsCollection)
+ {
+ builder.Append(" Collection");
+ }
+
+ builder.Append(TargetEntityType.DisplayName());
+
+ if (Inverse != null)
+ {
+ builder.Append(" Inverse: ").Append(Inverse.Name);
+ }
+
+ if (GetPropertyAccessMode() != PropertyAccessMode.PreferField)
+ {
+ builder.Append(" PropertyAccessMode.").Append(GetPropertyAccessMode());
+ }
+
+ if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
+ && ((Annotatable)this).IsReadOnly)
+ {
+ var indexes = ((ISkipNavigation)this).GetPropertyIndexes();
+ builder.Append(" ").Append(indexes.Index);
+ builder.Append(" ").Append(indexes.OriginalValueIndex);
+ builder.Append(" ").Append(indexes.RelationshipIndex);
+ builder.Append(" ").Append(indexes.ShadowIndex);
+ builder.Append(" ").Append(indexes.StoreGenerationIndex);
+ }
+
+ if (!singleLine && (options & MetadataDebugStringOptions.IncludeAnnotations) != 0)
+ {
+ builder.Append(AnnotationsToDebugString(indent + 2));
+ }
+
+ return builder.ToString();
+ }
}
}
diff --git a/src/EFCore/Metadata/Internal/IndexExtensions.cs b/src/EFCore/Metadata/Internal/IRuntimeSkipNavigation.cs
similarity index 78%
rename from src/EFCore/Metadata/Internal/IndexExtensions.cs
rename to src/EFCore/Metadata/Internal/IRuntimeSkipNavigation.cs
index f99b66dc1e3..a42369eaa87 100644
--- a/src/EFCore/Metadata/Internal/IndexExtensions.cs
+++ b/src/EFCore/Metadata/Internal/IRuntimeSkipNavigation.cs
@@ -1,11 +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.Runtime.CompilerServices;
-using JetBrains.Annotations;
-
#nullable enable
+using Microsoft.EntityFrameworkCore.Internal;
+
namespace Microsoft.EntityFrameworkCore.Metadata.Internal
{
///
@@ -14,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal
/// 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 static class IndexExtensions
+ public interface IRuntimeSkipNavigation : ISkipNavigation
{
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -22,7 +21,6 @@ public static class IndexExtensions
/// 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 static Index AsIndex([NotNull] this IReadOnlyIndex index, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(index, methodName);
+ ICollectionLoader GetManyToManyLoader();
}
}
diff --git a/src/EFCore/Metadata/Internal/Index.cs b/src/EFCore/Metadata/Internal/Index.cs
index 78fb778c0a9..ed2fd159121 100644
--- a/src/EFCore/Metadata/Internal/Index.cs
+++ b/src/EFCore/Metadata/Internal/Index.cs
@@ -242,7 +242,7 @@ public virtual IDependentKeyValueFactory GetNullableValueFactory()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public override string ToString()
- => this.ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
+ => ((IIndex)this).ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -252,8 +252,8 @@ public override string ToString()
///
public virtual DebugView DebugView
=> new(
- () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
- () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
+ () => ((IIndex)this).ToDebugString(MetadataDebugStringOptions.ShortDefault),
+ () => ((IIndex)this).ToDebugString(MetadataDebugStringOptions.LongDefault));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Metadata/Internal/InternalNavigationBuilder.cs b/src/EFCore/Metadata/Internal/InternalNavigationBuilder.cs
index 02a4477eba9..ce6b071f587 100644
--- a/src/EFCore/Metadata/Internal/InternalNavigationBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalNavigationBuilder.cs
@@ -84,7 +84,15 @@ public virtual bool CanSetAutoInclude(bool? autoInclude, ConfigurationSource con
{
if (CanSetAutoInclude(autoInclude, configurationSource))
{
- Metadata.SetIsEagerLoaded(autoInclude, configurationSource);
+ if (configurationSource == ConfigurationSource.Explicit)
+ {
+ ((IMutableNavigation)Metadata).SetIsEagerLoaded(autoInclude);
+ }
+ else
+ {
+ ((IConventionNavigation)Metadata).SetIsEagerLoaded(
+ autoInclude, configurationSource == ConfigurationSource.DataAnnotation);
+ }
return this;
}
diff --git a/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs b/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
index 096999b35db..49215affa7e 100644
--- a/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
@@ -335,7 +335,15 @@ public virtual bool CanSetAutoInclude(bool? autoInclude, ConfigurationSource con
{
if (CanSetAutoInclude(autoInclude, configurationSource))
{
- Metadata.SetIsEagerLoaded(autoInclude, configurationSource);
+ if (configurationSource == ConfigurationSource.Explicit)
+ {
+ ((IMutableSkipNavigation)Metadata).SetIsEagerLoaded(autoInclude);
+ }
+ else
+ {
+ ((IConventionSkipNavigation)Metadata).SetIsEagerLoaded(
+ autoInclude, configurationSource == ConfigurationSource.DataAnnotation);
+ }
return this;
}
diff --git a/src/EFCore/Metadata/Internal/Navigation.cs b/src/EFCore/Metadata/Internal/Navigation.cs
index fd7f02bc040..871050a2218 100644
--- a/src/EFCore/Metadata/Internal/Navigation.cs
+++ b/src/EFCore/Metadata/Internal/Navigation.cs
@@ -172,15 +172,6 @@ public override void UpdateConfigurationSource(ConfigurationSource configuration
}
}
- ///
- /// 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? SetIsEagerLoaded(bool? eagerLoaded, ConfigurationSource configurationSource)
- => (bool?)SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, configurationSource)?.Value;
-
///
/// 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
@@ -337,7 +328,7 @@ public virtual IClrCollectionAccessor? CollectionAccessor
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public override string ToString()
- => this.ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
+ => ((IReadOnlyNavigation)this).ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -347,8 +338,8 @@ public override string ToString()
///
public virtual DebugView DebugView
=> new(
- () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
- () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
+ () => ((IReadOnlyNavigation)this).ToDebugString(MetadataDebugStringOptions.ShortDefault),
+ () => ((IReadOnlyNavigation)this).ToDebugString(MetadataDebugStringOptions.LongDefault));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -392,5 +383,14 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
{
[DebuggerStepThrough] get => Builder;
}
+
+ ///
+ /// 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.
+ ///
+ IClrCollectionAccessor? INavigationBase.GetCollectionAccessor()
+ => CollectionAccessor;
}
}
diff --git a/src/EFCore/Metadata/Internal/NavigationExtensions.cs b/src/EFCore/Metadata/Internal/NavigationExtensions.cs
index 99681905a3e..37cb9c34a1b 100644
--- a/src/EFCore/Metadata/Internal/NavigationExtensions.cs
+++ b/src/EFCore/Metadata/Internal/NavigationExtensions.cs
@@ -1,9 +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.Runtime.CompilerServices;
using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Internal;
#nullable enable
@@ -27,23 +25,5 @@ public static MemberIdentity CreateMemberIdentity([CanBeNull] this IReadOnlyNavi
=> navigation?.GetIdentifyingMemberInfo() == null
? MemberIdentity.Create(navigation?.Name)
: MemberIdentity.Create(navigation.GetIdentifyingMemberInfo());
-
- ///
- /// 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 static Navigation AsNavigation([NotNull] this IReadOnlyNavigation navigation, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(navigation, methodName);
-
- ///
- /// 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 static ICollectionLoader GetManyToManyLoader([NotNull] this IReadOnlySkipNavigation navigation)
- => ((SkipNavigation)navigation).ManyToManyLoader;
}
}
diff --git a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
index 7214f59fafc..7d44530529e 100644
--- a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
+++ b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
@@ -3,7 +3,6 @@
using System.Linq;
using System.Reflection;
-using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
diff --git a/src/EFCore/Metadata/Internal/ServiceProperty.cs b/src/EFCore/Metadata/Internal/ServiceProperty.cs
index 8dba52349f7..cdc4b9da11f 100644
--- a/src/EFCore/Metadata/Internal/ServiceProperty.cs
+++ b/src/EFCore/Metadata/Internal/ServiceProperty.cs
@@ -241,7 +241,7 @@ IEntityType IServiceProperty.DeclaringEntityType
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public override string ToString()
- => this.ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
+ => ((IServiceProperty)this).ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -251,7 +251,7 @@ public override string ToString()
///
public virtual DebugView DebugView
=> new(
- () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
- () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
+ () => ((IServiceProperty)this).ToDebugString(MetadataDebugStringOptions.ShortDefault),
+ () => ((IServiceProperty)this).ToDebugString(MetadataDebugStringOptions.LongDefault));
}
}
diff --git a/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs b/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs
deleted file mode 100644
index 23beb340456..00000000000
--- a/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.Runtime.CompilerServices;
-using JetBrains.Annotations;
-
-#nullable enable
-
-namespace Microsoft.EntityFrameworkCore.Metadata.Internal
-{
- ///
- /// 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 static class ServicePropertyExtensions
- {
- ///
- /// 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 static ServiceProperty AsServiceProperty(
- [NotNull] this IReadOnlyServiceProperty serviceProperty,
- [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(serviceProperty, methodName);
- }
-}
diff --git a/src/EFCore/Metadata/Internal/SkipNavigation.cs b/src/EFCore/Metadata/Internal/SkipNavigation.cs
index dd990e8ddb4..565efa04880 100644
--- a/src/EFCore/Metadata/Internal/SkipNavigation.cs
+++ b/src/EFCore/Metadata/Internal/SkipNavigation.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal
/// 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 class SkipNavigation : PropertyBase, IMutableSkipNavigation, IConventionSkipNavigation, ISkipNavigation
+ public class SkipNavigation : PropertyBase, IMutableSkipNavigation, IConventionSkipNavigation, IRuntimeSkipNavigation
{
private ConfigurationSource? _foreignKeyConfigurationSource;
private ConfigurationSource? _inverseConfigurationSource;
@@ -322,15 +322,6 @@ public virtual void UpdateForeignKeyConfigurationSource(ConfigurationSource conf
public virtual void UpdateInverseConfigurationSource(ConfigurationSource configurationSource)
=> _inverseConfigurationSource = _inverseConfigurationSource.Max(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 bool? SetIsEagerLoaded(bool? eagerLoaded, ConfigurationSource configurationSource)
- => (bool?)SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, configurationSource)?.Value;
-
///
/// 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
@@ -392,10 +383,9 @@ public virtual ICollectionLoader ManyToManyLoader
/// 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 DebugView DebugView
- => new(
- () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
- () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
+ [DebuggerStepThrough]
+ public override string ToString()
+ => ((IReadOnlySkipNavigation)this).ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -403,9 +393,10 @@ public virtual DebugView DebugView
/// 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 override string ToString()
- => this.ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
+ public virtual DebugView DebugView
+ => new(
+ () => ((IReadOnlySkipNavigation)this).ToDebugString(MetadataDebugStringOptions.ShortDefault),
+ () => ((IReadOnlySkipNavigation)this).ToDebugString(MetadataDebugStringOptions.LongDefault));
///
IConventionSkipNavigationBuilder IConventionSkipNavigation.Builder
@@ -474,5 +465,23 @@ IReadOnlySkipNavigation IReadOnlySkipNavigation.Inverse
bool fromDataAnnotation)
=> SetInverse(
(SkipNavigation?)inverse, 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.
+ ///
+ IClrCollectionAccessor? INavigationBase.GetCollectionAccessor()
+ => CollectionAccessor;
+
+ ///
+ /// 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.
+ ///
+ ICollectionLoader IRuntimeSkipNavigation.GetManyToManyLoader()
+ => ManyToManyLoader;
}
}
diff --git a/test/EFCore.Tests/ApiConsistencyTest.cs b/test/EFCore.Tests/ApiConsistencyTest.cs
index 16224df37c2..e5df2764c10 100644
--- a/test/EFCore.Tests/ApiConsistencyTest.cs
+++ b/test/EFCore.Tests/ApiConsistencyTest.cs
@@ -100,14 +100,6 @@ public override
typeof(ConventionForeignKeyExtensions),
null,
null
- ),
- (
- typeof(IReadOnlyNavigation),
- typeof(NavigationExtensions),
- typeof(MutableNavigationExtensions),
- typeof(ConventionNavigationExtensions),
- null,
- null
)
};
diff --git a/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs b/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs
index a27667a56b7..2f3723520c2 100644
--- a/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs
+++ b/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs
@@ -72,6 +72,9 @@ public object GetOrCreate(object entity, bool forMaterialization)
public IComparer GetCurrentValueComparer()
=> throw new NotImplementedException();
+ public IClrCollectionAccessor GetCollectionAccessor()
+ => throw new NotImplementedException();
+
public Type CollectionType { get; }
}
diff --git a/test/EFCore.Tests/Metadata/Internal/NavigationTest.cs b/test/EFCore.Tests/Metadata/Internal/NavigationTest.cs
index d466e20f10b..964ae43682a 100644
--- a/test/EFCore.Tests/Metadata/Internal/NavigationTest.cs
+++ b/test/EFCore.Tests/Metadata/Internal/NavigationTest.cs
@@ -5,35 +5,12 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
-using Microsoft.EntityFrameworkCore.Infrastructure;
using Xunit;
namespace Microsoft.EntityFrameworkCore.Metadata.Internal
{
public class NavigationTest
{
- [ConditionalFact]
- public void Use_of_custom_INavigation_throws()
- {
- var navigation = new FakeNavigation();
-
- Assert.Equal(
- CoreStrings.CustomMetadata(nameof(Use_of_custom_INavigation_throws), nameof(IReadOnlyNavigation), nameof(FakeNavigation)),
- Assert.Throws(() => navigation.AsNavigation()).Message);
- }
-
- private class FakeNavigation : Annotatable, IReadOnlyNavigation
- {
- public string Name { get; }
- public IReadOnlyTypeBase DeclaringType { get; }
- public Type ClrType { get; }
- public PropertyInfo PropertyInfo { get; }
- public FieldInfo FieldInfo { get; }
- public IReadOnlyEntityType DeclaringEntityType { get; }
- public IReadOnlyForeignKey ForeignKey { get; }
- public bool IsEagerLoaded { get; }
- }
-
[ConditionalFact]
public void Can_create_navigation()
{