diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
index 45df40bf3e2..a7cc3574088 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for Cosmos metadata.
+ /// Entity type extension methods for Cosmos metadata.
///
public static class CosmosEntityTypeExtensions
{
@@ -21,13 +21,13 @@ public static class CosmosEntityTypeExtensions
///
/// The entity type to get the container name for.
/// The name of the container to which the entity type is mapped.
- public static string? GetContainer([NotNull] this IEntityType entityType)
+ public static string? GetContainer([NotNull] this IReadOnlyEntityType entityType)
=> entityType.BaseType != null
? entityType.GetRootType().GetContainer()
: (string?)entityType[CosmosAnnotationNames.ContainerName]
?? GetDefaultContainer(entityType);
- private static string? GetDefaultContainer(IEntityType entityType)
+ private static string? GetDefaultContainer(IReadOnlyEntityType entityType)
=> entityType.IsOwned()
? null
: entityType.Model.GetDefaultContainer()
@@ -72,11 +72,11 @@ public static void SetContainer(
///
/// The entity type to get the containing property name for.
/// The name of the parent property to which the entity type is mapped.
- public static string? GetContainingPropertyName([NotNull] this IEntityType entityType)
+ public static string? GetContainingPropertyName([NotNull] this IReadOnlyEntityType entityType)
=> entityType[CosmosAnnotationNames.PropertyName] as string
?? GetDefaultContainingPropertyName(entityType);
- private static string? GetDefaultContainingPropertyName(IEntityType entityType)
+ private static string? GetDefaultContainingPropertyName(IReadOnlyEntityType entityType)
=> entityType.FindOwnership()?.PrincipalToDependent!.Name;
///
@@ -118,7 +118,7 @@ public static void SetContainingPropertyName(
///
/// The entity type to get the partition key property name for.
/// The name of the partition key property.
- public static string? GetPartitionKeyPropertyName([NotNull] this IEntityType entityType)
+ public static string? GetPartitionKeyPropertyName([NotNull] this IReadOnlyEntityType entityType)
=> entityType[CosmosAnnotationNames.PartitionKeyName] as string;
///
@@ -156,15 +156,15 @@ public static void SetPartitionKeyPropertyName(
?.GetConfigurationSource();
///
- /// Returns the name of the property that is used to store the etag.
+ /// Returns the name of the property that is used to store the ETag.
///
/// The entity type to get the etag property name for.
/// The name of the etag property.
- public static string? GetETagPropertyName([NotNull] this IEntityType entityType)
+ public static string? GetETagPropertyName([NotNull] this IReadOnlyEntityType entityType)
=> entityType[CosmosAnnotationNames.ETagName] as string;
///
- /// Sets the name of the property that is used to store the etag key.
+ /// Sets the name of the property that is used to store the ETag key.
///
/// The entity type to set the etag property name for.
/// The name to set.
@@ -174,9 +174,9 @@ public static void SetETagPropertyName([NotNull] this IMutableEntityType entityT
Check.NullButNotEmpty(name, nameof(name)));
///
- /// Sets the name of the property that is used to store the etag.
+ /// Sets the name of the property that is used to store the ETag.
///
- /// The entity type to set the etag property name for.
+ /// The entity type to set the ETag property name for.
/// The name to set.
/// Indicates whether the configuration was specified using a data annotation.
public static void SetETagPropertyName(
@@ -198,15 +198,23 @@ public static void SetETagPropertyName(
?.GetConfigurationSource();
///
- /// Gets the on this entity that is mapped to cosmos etag, if it exists.
+ /// Gets the property on this entity that is mapped to cosmos ETag, if it exists.
///
- /// The entity type to get the etag property for.
- /// The mapped to etag, or null if no property is mapped to etag.
- public static IProperty? GetETagProperty([NotNull] this IEntityType entityType)
+ /// The entity type to get the ETag property for.
+ /// The property mapped to ETag, or if no property is mapped to ETag.
+ public static IReadOnlyProperty? GetETagProperty([NotNull] this IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
var etagPropertyName = entityType.GetETagPropertyName();
return !string.IsNullOrEmpty(etagPropertyName) ? entityType.FindProperty(etagPropertyName) : null;
}
+
+ ///
+ /// Gets the property on this entity that is mapped to cosmos ETag, if it exists.
+ ///
+ /// The entity type to get the ETag property for.
+ /// The property mapped to etag, or if no property is mapped to ETag.
+ public static IProperty? GetETagProperty([NotNull] this IEntityType entityType)
+ => (IProperty?)((IReadOnlyEntityType)entityType).GetETagProperty();
}
}
diff --git a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs
index 80b4de7d1a2..e4579226e5d 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for Cosmos metadata.
+ /// Model extension methods for Cosmos metadata.
///
public static class CosmosModelExtensions
{
@@ -21,7 +21,7 @@ public static class CosmosModelExtensions
///
/// The model.
/// The default container name.
- public static string? GetDefaultContainer([NotNull] this IModel model)
+ public static string? GetDefaultContainer([NotNull] this IReadOnlyModel model)
=> (string?)model[CosmosAnnotationNames.ContainerName];
///
diff --git a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
index 4fb7a1a0f88..b62728b94f8 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for Cosmos metadata.
+ /// Property extension methods for Cosmos metadata.
///
public static class CosmosPropertyExtensions
{
@@ -21,11 +21,11 @@ public static class CosmosPropertyExtensions
///
/// The property.
/// Returns the property name that the property is mapped to when targeting Cosmos.
- public static string GetJsonPropertyName([NotNull] this IProperty property)
+ public static string GetJsonPropertyName([NotNull] this IReadOnlyProperty property)
=> (string?)property[CosmosAnnotationNames.PropertyName]
?? GetDefaultJsonPropertyName(property);
- private static string GetDefaultJsonPropertyName(IProperty property)
+ private static string GetDefaultJsonPropertyName(IReadOnlyProperty property)
{
var entityType = property.DeclaringEntityType;
var ownership = entityType.FindOwnership();
diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs
index e901135d272..a07a63542a1 100644
--- a/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs
+++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosEntityTypeExtensions.cs
@@ -22,7 +22,7 @@ public static class CosmosEntityTypeExtensions
/// 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 bool IsDocumentRoot([NotNull] this IEntityType entityType)
+ public static bool IsDocumentRoot([NotNull] this IReadOnlyEntityType entityType)
=> entityType.BaseType?.IsDocumentRoot()
?? (!entityType.IsOwned()
|| entityType[CosmosAnnotationNames.ContainerName] != null);
diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs
index 18f8de69351..e802105e741 100644
--- a/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs
+++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosNavigationExtensions.cs
@@ -22,7 +22,7 @@ public static class CosmosNavigationExtensions
/// 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 bool IsEmbedded([NotNull] this INavigation navigation)
+ public static bool IsEmbedded([NotNull] this IReadOnlyNavigation navigation)
=> !navigation.IsOnDependent
&& !navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot();
}
diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs
index c6c696422d8..89fe14458ba 100644
--- a/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs
+++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs
@@ -23,13 +23,13 @@ public static class CosmosPropertyExtensions
/// 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 bool IsOrdinalKeyProperty([NotNull] this IProperty property)
+ public static bool IsOrdinalKeyProperty([NotNull] this IReadOnlyProperty property)
{
Check.DebugAssert(
property.DeclaringEntityType.IsOwned(), $"Expected {property.DeclaringEntityType.DisplayName()} to be owned.");
Check.DebugAssert(property.GetJsonPropertyName().Length == 0, $"Expected {property.Name} to be non-persisted.");
- return property.FindContainingPrimaryKey() is IKey key
+ return property.FindContainingPrimaryKey() is IReadOnlyKey key
&& key.Properties.Count > 1
&& !property.IsForeignKey()
&& property.ClrType == typeof(int)
diff --git a/src/EFCore.Design/Metadata/Internal/ScaffoldingEntityTypeAnnotations.cs b/src/EFCore.Design/Metadata/Internal/ScaffoldingEntityTypeAnnotations.cs
index f3f676955b9..ed01c7dceb1 100644
--- a/src/EFCore.Design/Metadata/Internal/ScaffoldingEntityTypeAnnotations.cs
+++ b/src/EFCore.Design/Metadata/Internal/ScaffoldingEntityTypeAnnotations.cs
@@ -20,7 +20,7 @@ public static class ScaffoldingEntityTypeAnnotations
/// 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 string GetDbSetName([NotNull] this IEntityType entityType)
+ public static string GetDbSetName([NotNull] this IReadOnlyEntityType entityType)
=> (string)entityType[ScaffoldingAnnotationNames.DbSetName]
?? entityType.Name;
diff --git a/src/EFCore.Design/Metadata/Internal/ScaffoldingModelExtensions.cs b/src/EFCore.Design/Metadata/Internal/ScaffoldingModelExtensions.cs
index 0dda926192c..d2fba9b1699 100644
--- a/src/EFCore.Design/Metadata/Internal/ScaffoldingModelExtensions.cs
+++ b/src/EFCore.Design/Metadata/Internal/ScaffoldingModelExtensions.cs
@@ -21,7 +21,16 @@ public static class ScaffoldingModelExtensions
/// 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 IDictionary GetEntityTypeErrors([NotNull] this IModel model)
+ public static IReadOnlyDictionary GetEntityTypeErrors([NotNull] this IReadOnlyModel model)
+ => (IReadOnlyDictionary)model[ScaffoldingAnnotationNames.EntityTypeErrors] ?? new Dictionary();
+
+ ///
+ /// 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 IDictionary GetOrCreateEntityTypeErrors([NotNull] this IReadOnlyModel model)
{
var errors = (IDictionary)model[ScaffoldingAnnotationNames.EntityTypeErrors];
if (errors == null)
@@ -50,7 +59,7 @@ public static void SetEntityTypeErrors([NotNull] this IMutableModel model, [NotN
/// 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 string GetDatabaseName([NotNull] this IModel model)
+ public static string GetDatabaseName([NotNull] this IReadOnlyModel model)
=> (string)model[ScaffoldingAnnotationNames.DatabaseName];
///
diff --git a/src/EFCore.Design/Metadata/Internal/ScaffoldingPropertyExtensions.cs b/src/EFCore.Design/Metadata/Internal/ScaffoldingPropertyExtensions.cs
index 68ba429e131..16657b13951 100644
--- a/src/EFCore.Design/Metadata/Internal/ScaffoldingPropertyExtensions.cs
+++ b/src/EFCore.Design/Metadata/Internal/ScaffoldingPropertyExtensions.cs
@@ -19,7 +19,7 @@ public static class ScaffoldingPropertyExtensions
/// 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 int GetColumnOrdinal([NotNull] this IProperty property)
+ public static int GetColumnOrdinal([NotNull] this IReadOnlyProperty property)
=> (int?)property[ScaffoldingAnnotationNames.ColumnOrdinal] ?? -1;
///
diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
index 8a2903667de..549d77d732f 100644
--- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
+++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
@@ -232,7 +232,11 @@ protected virtual void GenerateEntityType(
GenerateProperties(builderName, entityType.GetDeclaredProperties(), stringBuilder);
- GenerateKeys(builderName, entityType.GetDeclaredKeys(), entityType.FindDeclaredPrimaryKey(), stringBuilder);
+ GenerateKeys(
+ builderName,
+ entityType.GetDeclaredKeys(),
+ entityType.BaseType == null ? entityType.FindPrimaryKey() : null,
+ stringBuilder);
GenerateIndexes(builderName, entityType.GetDeclaredIndexes(), stringBuilder);
diff --git a/src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs b/src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs
index 6f1cee89f3a..4accc11bd28 100644
--- a/src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs
+++ b/src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs
@@ -20,6 +20,6 @@ public interface ISnapshotModelProcessor
/// 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.
///
- IModel Process([CanBeNull] IModel model);
+ IModel Process([CanBeNull] IReadOnlyModel model);
}
}
diff --git a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs b/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs
index 608f971b7a5..ad05924cd0e 100644
--- a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs
+++ b/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs
@@ -51,7 +51,7 @@ public SnapshotModelProcessor(
/// 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 IModel Process(IModel model)
+ public virtual IModel Process(IReadOnlyModel model)
{
if (model == null)
{
@@ -85,10 +85,10 @@ public virtual IModel Process(IModel model)
model = mutableModel.FinalizeModel();
}
- return _modelRuntimeInitializer.Initialize(model, validationLogger: null);
+ return _modelRuntimeInitializer.Initialize((IModel)model, validationLogger: null);
}
- private void ProcessCollection(IEnumerable metadata, string version)
+ private void ProcessCollection(IEnumerable metadata, string version)
{
foreach (var element in metadata)
{
@@ -96,9 +96,9 @@ private void ProcessCollection(IEnumerable metadata, string versio
}
}
- private void ProcessElement(IEntityType entityType, string version)
+ private void ProcessElement(IReadOnlyEntityType entityType, string version)
{
- ProcessElement((IAnnotatable)entityType, version);
+ ProcessElement((IReadOnlyAnnotatable)entityType, version);
if ((version.StartsWith("2.0", StringComparison.Ordinal)
|| version.StartsWith("2.1", StringComparison.Ordinal))
@@ -109,7 +109,7 @@ private void ProcessElement(IEntityType entityType, string version)
}
}
- private void ProcessElement(IAnnotatable metadata, string version)
+ private void ProcessElement(IReadOnlyAnnotatable metadata, string version)
{
if (version.StartsWith("1.", StringComparison.Ordinal)
&& metadata is IMutableAnnotatable mutableMetadata)
@@ -141,7 +141,7 @@ private void ProcessElement(IAnnotatable metadata, string version)
}
}
- private void UpdateSequences(IModel model, string version)
+ private void UpdateSequences(IReadOnlyModel model, string version)
{
if ((!version.StartsWith("1.", StringComparison.Ordinal)
&& !version.StartsWith("2.", StringComparison.Ordinal)
diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs
index effcf385165..0b37923dcc8 100644
--- a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs
@@ -183,12 +183,13 @@ private void GenerateDbSets(IModel model)
private void GenerateEntityTypeErrors(IModel model)
{
- foreach (var entityTypeError in model.GetEntityTypeErrors())
+ var errors = model.GetEntityTypeErrors();
+ foreach (var entityTypeError in errors)
{
_sb.AppendLine($"// {entityTypeError.Value} Please see the warning messages.");
}
- if (model.GetEntityTypeErrors().Count > 0)
+ if (errors.Count > 0)
{
_sb.AppendLine();
}
@@ -454,11 +455,11 @@ private void GenerateKey(IKey key, IEntityType entityType, bool useDataAnnotatio
if (key.Properties.Count == 1
&& annotations.Count == 0)
{
- if (key is Key concreteKey
- && key.Properties.SequenceEqual(
+ if (key is IConventionKey conventionKey
+ && conventionKey.Properties.SequenceEqual(
KeyDiscoveryConvention.DiscoverKeyProperties(
- concreteKey.DeclaringEntityType,
- concreteKey.DeclaringEntityType.GetProperties())))
+ conventionKey.DeclaringEntityType,
+ conventionKey.DeclaringEntityType.GetProperties())))
{
return;
}
diff --git a/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs b/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs
index 138e6d75093..b74d10f8ca5 100644
--- a/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs
@@ -43,7 +43,7 @@ public virtual string GenerateCandidateIdentifier(DatabaseColumn originalColumn)
/// 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 string GetDependentEndCandidateNavigationPropertyName(IForeignKey foreignKey)
+ public virtual string GetDependentEndCandidateNavigationPropertyName(IReadOnlyForeignKey foreignKey)
{
Check.NotNull(foreignKey, nameof(foreignKey));
@@ -59,7 +59,7 @@ public virtual string GetDependentEndCandidateNavigationPropertyName(IForeignKey
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual string GetPrincipalEndCandidateNavigationPropertyName(
- IForeignKey foreignKey,
+ IReadOnlyForeignKey foreignKey,
string dependentEndNavigationPropertyName)
{
Check.NotNull(foreignKey, nameof(foreignKey));
@@ -109,7 +109,7 @@ private static string GenerateCandidateIdentifier(string originalIdentifier)
return candidateStringBuilder.ToString();
}
- private static string FindCandidateNavigationName(IEnumerable properties)
+ private static string FindCandidateNavigationName(IEnumerable properties)
{
if (!properties.Any())
{
diff --git a/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs b/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs
index 6897c0f62b4..ff77da82006 100644
--- a/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs
@@ -37,7 +37,7 @@ public interface ICandidateNamingService
/// 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.
///
- string GetDependentEndCandidateNavigationPropertyName([NotNull] IForeignKey foreignKey);
+ string GetDependentEndCandidateNavigationPropertyName([NotNull] IReadOnlyForeignKey foreignKey);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -46,7 +46,7 @@ public interface ICandidateNamingService
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
string GetPrincipalEndCandidateNavigationPropertyName(
- [NotNull] IForeignKey foreignKey,
+ [NotNull] IReadOnlyForeignKey foreignKey,
[NotNull] string dependentEndNavigationPropertyName);
}
}
diff --git a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs
index aeb096c05e1..f8659453cae 100644
--- a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs
@@ -108,7 +108,7 @@ public virtual IModel Create(DatabaseModel databaseModel, ModelReverseEngineerOp
VisitDatabaseModel(modelBuilder, databaseModel);
- return modelBuilder.Model;
+ return modelBuilder.FinalizeModel();
}
///
@@ -359,7 +359,7 @@ protected virtual EntityTypeBuilder VisitTable([NotNull] ModelBuilder modelBuild
var model = modelBuilder.Model;
model.RemoveEntityType(entityTypeName);
- model.GetEntityTypeErrors().Add(entityTypeName, errorMessage);
+ model.GetOrCreateEntityTypeErrors().Add(entityTypeName, errorMessage);
return null;
}
}
@@ -928,7 +928,7 @@ protected virtual void AddNavigationProperties([NotNull] IMutableForeignKey fore
}
// Stores the names of the EntityType itself and its Properties, but does not include any Navigation Properties
- private readonly Dictionary> _entityTypeAndPropertyIdentifiers =
+ private readonly Dictionary> _entityTypeAndPropertyIdentifiers =
new();
///
@@ -937,7 +937,7 @@ protected virtual void AddNavigationProperties([NotNull] IMutableForeignKey fore
/// 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.
///
- protected virtual List ExistingIdentifiers([NotNull] IEntityType entityType)
+ protected virtual List ExistingIdentifiers([NotNull] IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
diff --git a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs
index 50108930b58..0d9ba49ec46 100644
--- a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs
@@ -124,7 +124,6 @@ public virtual ScaffoldedModel ScaffoldModel(
}
var model = _factory.Create(databaseModel, modelOptions);
-
if (model == null)
{
throw new InvalidOperationException(
diff --git a/src/EFCore.InMemory/Extensions/InMemoryEntityTypeExtensions.cs b/src/EFCore.InMemory/Extensions/InMemoryEntityTypeExtensions.cs
index 123181eabfc..178d6cadfcd 100644
--- a/src/EFCore.InMemory/Extensions/InMemoryEntityTypeExtensions.cs
+++ b/src/EFCore.InMemory/Extensions/InMemoryEntityTypeExtensions.cs
@@ -13,7 +13,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for the in-memory provider.
+ /// Extension methods for for the in-memory provider.
///
public static class InMemoryEntityTypeExtensions
{
@@ -22,7 +22,7 @@ public static class InMemoryEntityTypeExtensions
///
/// The entity type to get the in-memory query for.
/// The LINQ query used as the default source.
- public static LambdaExpression? GetInMemoryQuery([NotNull] this IEntityType entityType)
+ public static LambdaExpression? GetInMemoryQuery([NotNull] this IReadOnlyEntityType entityType)
#pragma warning disable EF1001 // Internal EF Core API usage.
#pragma warning disable CS0612 // Type or member is obsolete
=> (LambdaExpression?)Check.NotNull(entityType, nameof(entityType))[CoreAnnotationNames.DefiningQuery];
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
index 60bf77b3c4f..c3b65ba8a92 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
@@ -291,7 +291,7 @@ public ShaperRemappingExpressionVisitor(IDictionary GetAllPropertiesInHierarchy(IEntityType entityType)
=> entityType.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredProperties);
+ .SelectMany(t => t.GetDeclaredProperties());
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -914,7 +914,7 @@ EntityProjectionExpression CopyEntityProjectionToOuter(EntityProjectionExpressio
// Also lift nested entity projections
foreach (var navigation in entityProjection.EntityType.GetAllBaseTypes()
.Concat(entityProjection.EntityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredNavigations))
+ .SelectMany(t => t.GetDeclaredNavigations()))
{
var boundEntityShaperExpression = entityProjection.BindNavigation(navigation);
if (boundEntityShaperExpression != null)
@@ -1165,7 +1165,7 @@ EntityProjectionExpression CopyEntityProjectionToOuter(EntityProjectionExpressio
// Also lift nested entity projections
foreach (var navigation in entityProjection.EntityType.GetAllBaseTypes()
.Concat(entityProjection.EntityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredNavigations))
+ .SelectMany(t => t.GetDeclaredNavigations()))
{
var boundEntityShaperExpression = entityProjection.BindNavigation(navigation);
if (boundEntityShaperExpression != null)
diff --git a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs
index b5b0b144eea..d9015ca89ce 100644
--- a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs
+++ b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs
@@ -73,7 +73,7 @@ public virtual void ProcessModelFinalizing(
throw new InvalidOperationException(ProxiesStrings.ItsASeal(entityType.DisplayName()));
}
- var proxyType = _proxyFactory.CreateProxyType(_options, entityType);
+ var proxyType = _proxyFactory.CreateProxyType(_options, (IEntityType)entityType);
// WARNING: This code is EF internal; it should not be copied. See #10789 #14554
#pragma warning disable EF1001 // Internal EF Core API usage.
@@ -211,7 +211,7 @@ void UpdateConstructorBindings(string bindingAnnotationName, InstantiationBindin
new ContextParameterBinding(typeof(DbContext)),
new EntityTypeParameterBinding(),
new DependencyInjectionParameterBinding(
- typeof(ILazyLoader), typeof(ILazyLoader), serviceProperty),
+ typeof(ILazyLoader), typeof(ILazyLoader), (IPropertyBase)serviceProperty),
new ObjectArrayParameterBinding(binding.ParameterBindings)
},
proxyType));
diff --git a/src/EFCore.Relational/Diagnostics/SequenceEventData.cs b/src/EFCore.Relational/Diagnostics/SequenceEventData.cs
index 93f2df5ab92..8bc8591e908 100644
--- a/src/EFCore.Relational/Diagnostics/SequenceEventData.cs
+++ b/src/EFCore.Relational/Diagnostics/SequenceEventData.cs
@@ -23,7 +23,7 @@ public class SequenceEventData : EventData
public SequenceEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] ISequence sequence)
+ [NotNull] IReadOnlySequence sequence)
: base(eventDefinition, messageGenerator)
{
Sequence = sequence;
@@ -32,6 +32,6 @@ public SequenceEventData(
///
/// The sequence.
///
- public virtual ISequence Sequence { get; }
+ public virtual IReadOnlySequence Sequence { get; }
}
}
diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
index f746f0a3d6b..65c93b13b24 100644
--- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
@@ -16,7 +16,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for relational database metadata.
+ /// Entity type extension methods for relational database metadata.
///
public static class RelationalEntityTypeExtensions
{
@@ -26,7 +26,7 @@ public static class RelationalEntityTypeExtensions
///
/// The entity type to get the table name for.
/// The name of the table to which the entity type is mapped.
- public static string? GetTableName([NotNull] this IEntityType entityType)
+ public static string? GetTableName([NotNull] this IReadOnlyEntityType entityType)
{
var nameAnnotation = entityType.FindAnnotation(RelationalAnnotationNames.TableName);
if (nameAnnotation != null)
@@ -55,7 +55,7 @@ public static class RelationalEntityTypeExtensions
/// The entity type to get the table name for.
/// A value indicating whether the name should be truncated to the max identifier length.
/// The default name of the table to which the entity type would be mapped.
- public static string? GetDefaultTableName([NotNull] this IEntityType entityType, bool truncate = true)
+ public static string? GetDefaultTableName([NotNull] this IReadOnlyEntityType entityType, bool truncate = true)
{
var ownership = entityType.FindOwnership();
if (ownership != null
@@ -126,7 +126,7 @@ public static void SetTableName([NotNull] this IMutableEntityType entityType, [C
///
/// The entity type to get the schema for.
/// The database schema that contains the mapped table.
- public static string? GetSchema([NotNull] this IEntityType entityType)
+ public static string? GetSchema([NotNull] this IReadOnlyEntityType entityType)
{
var schemaAnnotation = entityType.FindAnnotation(RelationalAnnotationNames.Schema);
if (schemaAnnotation != null)
@@ -144,7 +144,7 @@ public static void SetTableName([NotNull] this IMutableEntityType entityType, [C
///
/// The entity type to get the schema for.
/// The default database schema to which the entity type would be mapped.
- public static string? GetDefaultSchema([NotNull] this IEntityType entityType)
+ public static string? GetDefaultSchema([NotNull] this IReadOnlyEntityType entityType)
{
var ownership = entityType.FindOwnership();
if (ownership != null)
@@ -211,7 +211,7 @@ public static void SetSchema([NotNull] this IMutableEntityType entityType, [CanB
///
/// The entity type to get the table name for.
/// The name of the table to which the entity type is mapped prepended by the schema.
- public static string? GetSchemaQualifiedTableName([NotNull] this IEntityType entityType)
+ public static string? GetSchemaQualifiedTableName([NotNull] this IReadOnlyEntityType entityType)
{
var tableName = entityType.GetTableName();
if (tableName == null)
@@ -229,7 +229,7 @@ public static void SetSchema([NotNull] this IMutableEntityType entityType, [CanB
///
/// The entity type to get the table name for.
/// The name of the table to which the entity type is mapped prepended by the schema.
- public static string? GetSchemaQualifiedViewName([NotNull] this IEntityType entityType)
+ public static string? GetSchemaQualifiedViewName([NotNull] this IReadOnlyEntityType entityType)
{
var viewName = entityType.GetViewName();
if (viewName == null)
@@ -247,7 +247,8 @@ public static void SetSchema([NotNull] this IMutableEntityType entityType, [CanB
/// The entity type to get the table mappings for.
/// The tables to which the entity type is mapped.
public static IEnumerable GetDefaultMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.DefaultMappings)
+ => (IEnumerable?)entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.DefaultMappings)
?? Array.Empty();
///
@@ -256,7 +257,8 @@ public static IEnumerable GetDefaultMappings([NotNull] this I
/// The entity type to get the table mappings for.
/// The tables to which the entity type is mapped.
public static IEnumerable GetTableMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings)
+ => (IEnumerable?)entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.TableMappings)
?? Array.Empty();
///
@@ -264,7 +266,7 @@ public static IEnumerable GetTableMappings([NotNull] this IEntity
///
/// The entity type to get the view name for.
/// The name of the view to which the entity type is mapped.
- public static string? GetViewName([NotNull] this IEntityType entityType)
+ public static string? GetViewName([NotNull] this IReadOnlyEntityType entityType)
{
var nameAnnotation = (string?)entityType[RelationalAnnotationNames.ViewName];
if (nameAnnotation != null)
@@ -291,7 +293,7 @@ public static IEnumerable GetTableMappings([NotNull] this IEntity
///
/// The entity type to get the table name for.
/// The default name of the table to which the entity type would be mapped.
- public static string? GetDefaultViewName([NotNull] this IEntityType entityType)
+ public static string? GetDefaultViewName([NotNull] this IReadOnlyEntityType entityType)
{
var ownership = entityType.FindOwnership();
return ownership != null
@@ -344,7 +346,7 @@ public static void SetViewName([NotNull] this IMutableEntityType entityType, [Ca
///
/// The entity type to get the view schema for.
/// The database schema that contains the mapped view.
- public static string? GetViewSchema([NotNull] this IEntityType entityType)
+ public static string? GetViewSchema([NotNull] this IReadOnlyEntityType entityType)
{
var schemaAnnotation = entityType.FindAnnotation(RelationalAnnotationNames.ViewSchema);
if (schemaAnnotation != null)
@@ -362,7 +364,7 @@ public static void SetViewName([NotNull] this IMutableEntityType entityType, [Ca
///
/// The entity type to get the view schema for.
/// The default database schema to which the entity type would be mapped.
- public static string? GetDefaultViewSchema([NotNull] this IEntityType entityType)
+ public static string? GetDefaultViewSchema([NotNull] this IReadOnlyEntityType entityType)
{
var ownership = entityType.FindOwnership();
if (ownership != null
@@ -419,7 +421,8 @@ public static void SetViewSchema([NotNull] this IMutableEntityType entityType, [
/// The entity type to get the view mappings for.
/// The views to which the entity type is mapped.
public static IEnumerable GetViewMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.ViewMappings)
+ => (IEnumerable?)entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.ViewMappings)
?? Array.Empty();
///
@@ -428,7 +431,7 @@ public static IEnumerable GetViewMappings([NotNull] this IEntityTy
///
/// The entity type.
/// Gets the default SQL query name.
- public static string GetDefaultSqlQueryName([NotNull] this IEntityType entityType)
+ public static string GetDefaultSqlQueryName([NotNull] this IReadOnlyEntityType entityType)
=> entityType.Name + "." + SqlQueryExtensions.DefaultQueryNameBase;
///
@@ -436,7 +439,7 @@ public static string GetDefaultSqlQueryName([NotNull] this IEntityType entityTyp
///
/// The entity type.
/// The SQL string used to provide data for the entity type.
- public static string? GetSqlQuery([NotNull] this IEntityType entityType)
+ public static string? GetSqlQuery([NotNull] this IReadOnlyEntityType entityType)
{
var nameAnnotation = (string?)entityType[RelationalAnnotationNames.SqlQuery];
if (nameAnnotation != null)
@@ -493,7 +496,8 @@ public static void SetSqlQuery([NotNull] this IMutableEntityType entityType, [Ca
/// The entity type to get the function mappings for.
/// The functions to which the entity type is mapped.
public static IEnumerable GetSqlQueryMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.SqlQueryMappings)
+ => (IEnumerable?)entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.SqlQueryMappings)
?? Array.Empty();
///
@@ -501,7 +505,7 @@ public static IEnumerable GetSqlQueryMappings([NotNull] this I
///
/// The entity type to get the function name for.
/// The name of the function to which the entity type is mapped.
- public static string? GetFunctionName([NotNull] this IEntityType entityType)
+ public static string? GetFunctionName([NotNull] this IReadOnlyEntityType entityType)
{
var nameAnnotation = (string?)entityType[RelationalAnnotationNames.FunctionName];
if (nameAnnotation != null)
@@ -558,20 +562,21 @@ public static void SetFunctionName([NotNull] this IMutableEntityType entityType,
/// The entity type to get the function mappings for.
/// The functions to which the entity type is mapped.
public static IEnumerable GetFunctionMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.FunctionMappings)
+ => (IEnumerable?)entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.FunctionMappings)
?? Array.Empty();
///
- /// Finds an with the given name.
+ /// Finds an with the given name.
///
/// The entity type to find the check constraint for.
/// The check constraint name.
///
- /// The or if no check constraint with the
+ /// The or if no check constraint with the
/// given name in the given entity type was found.
///
- public static ICheckConstraint? FindCheckConstraint(
- [NotNull] this IEntityType entityType,
+ public static IReadOnlyCheckConstraint? FindCheckConstraint(
+ [NotNull] this IReadOnlyEntityType entityType,
[NotNull] string name)
{
Check.NotEmpty(name, nameof(name));
@@ -607,6 +612,20 @@ public static IEnumerable GetFunctionMappings([NotNull] this I
[NotNull] string name)
=> (IConventionCheckConstraint?)((IEntityType)entityType).FindCheckConstraint(name);
+ ///
+ /// Finds an with the given name.
+ ///
+ /// The entity type to find the check constraint for.
+ /// The check constraint name.
+ ///
+ /// The or if no check constraint with the
+ /// given name in the given entity type was found.
+ ///
+ public static ICheckConstraint? FindCheckConstraint(
+ [NotNull] this IEntityType entityType,
+ [NotNull] string name)
+ => (ICheckConstraint?)((IReadOnlyEntityType)entityType).FindCheckConstraint(name);
+
///
/// Creates a new check constraint with the given name on entity type. Throws an exception
/// if a check constraint with the same name exists on the same entity type.
@@ -672,10 +691,10 @@ public static IConventionCheckConstraint AddCheckConstraint(
=> CheckConstraint.RemoveCheckConstraint((IMutableEntityType)entityType, Check.NotEmpty(name, nameof(name)));
///
- /// Returns all contained in the entity type.
+ /// Returns all contained in the entity type.
///
/// The entity type to get the check constraints for.
- public static IEnumerable GetCheckConstraints([NotNull] this IEntityType entityType)
+ public static IEnumerable GetCheckConstraints([NotNull] this IReadOnlyEntityType entityType)
=> CheckConstraint.GetCheckConstraints(entityType);
///
@@ -692,12 +711,19 @@ public static IEnumerable GetCheckConstraints([NotNull]
public static IEnumerable GetCheckConstraints([NotNull] this IConventionEntityType entityType)
=> CheckConstraint.GetCheckConstraints(entityType);
+ ///
+ /// Returns all contained in the entity type.
+ ///
+ /// The entity type to get the check constraints for.
+ public static IEnumerable GetCheckConstraints([NotNull] this IEntityType entityType)
+ => CheckConstraint.GetCheckConstraints(entityType);
+
///
/// Returns the comment for the table this entity is mapped to.
///
/// The entity type.
/// The comment for the table this entity is mapped to.
- public static string? GetComment([NotNull] this IEntityType entityType)
+ public static string? GetComment([NotNull] this IReadOnlyEntityType entityType)
=> (string?)entityType[RelationalAnnotationNames.Comment];
///
@@ -740,8 +766,8 @@ public static void SetComment([NotNull] this IMutableEntityType entityType, [Can
///
/// The entity type.
/// The identifier of the store object.
- public static IEnumerable FindRowInternalForeignKeys(
- [NotNull] this IEntityType entityType,
+ public static IEnumerable FindRowInternalForeignKeys(
+ [NotNull] this IReadOnlyEntityType entityType,
StoreObjectIdentifier storeObject)
{
var primaryKey = entityType.FindPrimaryKey();
@@ -823,7 +849,7 @@ public static IEnumerable FindRowInternalForeignKeys(
///
/// The entity type.
/// A value indicating whether the associated table is ignored by Migrations.
- public static bool IsTableExcludedFromMigrations([NotNull] this IEntityType entityType)
+ public static bool IsTableExcludedFromMigrations([NotNull] this IReadOnlyEntityType entityType)
{
var excluded = (bool?)entityType[RelationalAnnotationNames.IsTableExcludedFromMigrations];
if (excluded != null)
diff --git a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
index f38ce583a8a..05ca9084255 100644
--- a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
@@ -15,7 +15,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for relational database metadata.
+ /// Foregn key extension methods for relational database metadata.
///
public static class RelationalForeignKeyExtensions
{
@@ -24,7 +24,7 @@ public static class RelationalForeignKeyExtensions
///
/// The foreign key.
/// The foreign key constraint name.
- public static string GetConstraintName([NotNull] this IForeignKey foreignKey)
+ public static string GetConstraintName([NotNull] this IReadOnlyForeignKey foreignKey)
{
var annotation = foreignKey.FindAnnotation(RelationalAnnotationNames.Name);
return annotation != null
@@ -40,7 +40,7 @@ public static string GetConstraintName([NotNull] this IForeignKey foreignKey)
/// The identifier of the principal store object.
/// The foreign key constraint name.
public static string? GetConstraintName(
- [NotNull] this IForeignKey foreignKey,
+ [NotNull] this IReadOnlyForeignKey foreignKey,
in StoreObjectIdentifier storeObject,
in StoreObjectIdentifier principalStoreObject)
{
@@ -55,7 +55,7 @@ public static string GetConstraintName([NotNull] this IForeignKey foreignKey)
///
/// The foreign key.
/// The default constraint name that would be used for this foreign key.
- public static string GetDefaultName([NotNull] this IForeignKey foreignKey)
+ public static string GetDefaultName([NotNull] this IReadOnlyForeignKey foreignKey)
{
var tableName = foreignKey.DeclaringEntityType.GetTableName();
var schema = foreignKey.DeclaringEntityType.GetSchema();
@@ -81,7 +81,7 @@ public static string GetDefaultName([NotNull] this IForeignKey foreignKey)
/// The identifier of the principal store object.
/// The default constraint name that would be used for this foreign key.
public static string? GetDefaultName(
- [NotNull] this IForeignKey foreignKey,
+ [NotNull] this IReadOnlyForeignKey foreignKey,
in StoreObjectIdentifier storeObject,
in StoreObjectIdentifier principalStoreObject)
{
@@ -99,7 +99,7 @@ public static string GetDefaultName([NotNull] this IForeignKey foreignKey)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IForeignKey? linkedForeignKey = null;
+ IReadOnlyForeignKey? linkedForeignKey = null;
foreach (var otherForeignKey in rootForeignKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys()))
@@ -190,7 +190,8 @@ public static void SetConstraintName([NotNull] this IMutableForeignKey foreignKe
/// The foreign key.
/// The foreign key constraints to which the foreign key is mapped.
public static IEnumerable GetMappedConstraints([NotNull] this IForeignKey foreignKey)
- => (IEnumerable?)foreignKey.FindRuntimeAnnotationValue(RelationalAnnotationNames.ForeignKeyMappings)
+ => (IEnumerable?)foreignKey.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.ForeignKeyMappings)
?? Enumerable.Empty();
///
@@ -205,8 +206,8 @@ public static IEnumerable GetMappedConstraints([NotNull]
/// The foreign key.
/// The identifier of the containing store object.
/// The foreign key if found, or if none was found.
- public static IForeignKey? FindSharedObjectRootForeignKey(
- [NotNull] this IForeignKey foreignKey,
+ public static IReadOnlyForeignKey? FindSharedObjectRootForeignKey(
+ [NotNull] this IReadOnlyForeignKey foreignKey,
in StoreObjectIdentifier storeObject)
{
Check.NotNull(foreignKey, nameof(foreignKey));
@@ -220,7 +221,7 @@ public static IEnumerable GetMappedConstraints([NotNull]
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IForeignKey? linkedForeignKey = null;
+ IReadOnlyForeignKey? linkedForeignKey = null;
foreach (var otherForeignKey in rootForeignKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys()))
diff --git a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
index afd84227752..d85316a4d62 100644
--- a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
@@ -16,7 +16,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for relational database metadata.
+ /// Index extension methods for relational database metadata.
///
public static class RelationalIndexExtensions
{
@@ -25,7 +25,7 @@ public static class RelationalIndexExtensions
///
/// The index.
/// The name of the index in the database.
- public static string GetDatabaseName([NotNull] this IIndex index)
+ public static string GetDatabaseName([NotNull] this IReadOnlyIndex index)
=> (string?)index[RelationalAnnotationNames.Name]
?? index.Name
?? index.GetDefaultDatabaseName();
@@ -45,7 +45,7 @@ public static string GetName([NotNull] this IIndex index)
/// The index.
/// The identifier of the store object.
/// The name of the index in the database.
- public static string? GetDatabaseName([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
+ public static string? GetDatabaseName([NotNull] this IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
=> (string?)index[RelationalAnnotationNames.Name]
?? index.Name
?? index.GetDefaultDatabaseName(storeObject);
@@ -55,7 +55,7 @@ public static string GetName([NotNull] this IIndex index)
///
/// The index.
/// The default name that would be used for this index.
- public static string GetDefaultDatabaseName([NotNull] this IIndex index)
+ public static string GetDefaultDatabaseName([NotNull] this IReadOnlyIndex index)
{
var tableName = index.DeclaringEntityType.GetTableName();
var schema = index.DeclaringEntityType.GetSchema();
@@ -84,7 +84,7 @@ public static string GetDefaultName([NotNull] this IIndex index)
/// The index.
/// The identifier of the store object.
/// The default name that would be used for this index.
- public static string? GetDefaultDatabaseName([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
+ public static string? GetDefaultDatabaseName([NotNull] this IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
{
var columnNames = index.Properties.GetColumnNames(storeObject);
if (columnNames == null)
@@ -98,7 +98,7 @@ public static string GetDefaultName([NotNull] this IIndex index)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IIndex? linkedIndex = null;
+ IReadOnlyIndex? linkedIndex = null;
foreach (var otherIndex in rootIndex.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetIndexes()))
@@ -208,7 +208,7 @@ public static void SetName([NotNull] this IConventionIndex index, [CanBeNull] st
///
/// The index.
/// The index filter expression.
- public static string? GetFilter([NotNull] this IIndex index)
+ public static string? GetFilter([NotNull] this IReadOnlyIndex index)
=> (string?)index.FindAnnotation(RelationalAnnotationNames.Filter)?.Value;
///
@@ -217,7 +217,7 @@ public static void SetName([NotNull] this IConventionIndex index, [CanBeNull] st
/// The index.
/// The identifier of the containing store object.
/// The index filter expression.
- public static string? GetFilter([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
+ public static string? GetFilter([NotNull] this IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
{
var annotation = index.FindAnnotation(RelationalAnnotationNames.Filter);
if (annotation != null)
@@ -270,7 +270,8 @@ public static void SetFilter([NotNull] this IMutableIndex index, [CanBeNull] str
/// The index.
/// The table indexes to which the index is mapped.
public static IEnumerable GetMappedTableIndexes([NotNull] this IIndex index)
- => (IEnumerable?)index.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableIndexMappings)
+ => (IEnumerable?)index.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.TableIndexMappings)
?? Enumerable.Empty();
///
@@ -285,7 +286,7 @@ public static IEnumerable GetMappedTableIndexes([NotNull] this IInd
/// The index.
/// The identifier of the containing store object.
/// The index found, or if none was found.
- public static IIndex? FindSharedObjectRootIndex([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
+ public static IReadOnlyIndex? FindSharedObjectRootIndex([NotNull] this IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
{
Check.NotNull(index, nameof(index));
@@ -296,7 +297,7 @@ public static IEnumerable GetMappedTableIndexes([NotNull] this IInd
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IIndex? linkedIndex = null;
+ IReadOnlyIndex? linkedIndex = null;
foreach (var otherIndex in rootIndex.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetIndexes()))
diff --git a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
index 400589cbc17..83621765740 100644
--- a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
@@ -15,7 +15,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for relational database metadata.
+ /// Key extension methods for relational database metadata.
///
public static class RelationalKeyExtensions
{
@@ -24,7 +24,7 @@ public static class RelationalKeyExtensions
///
/// The key.
/// The key constraint name for this key.
- public static string? GetName([NotNull] this IKey key)
+ public static string? GetName([NotNull] this IReadOnlyKey key)
=> key.GetName(StoreObjectIdentifier.Table(key.DeclaringEntityType.GetTableName()!, key.DeclaringEntityType.GetSchema()));
///
@@ -33,7 +33,7 @@ public static class RelationalKeyExtensions
/// The key.
/// The identifier of the containing store object.
/// The key constraint name for this key.
- public static string? GetName([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
+ public static string? GetName([NotNull] this IReadOnlyKey key, in StoreObjectIdentifier storeObject)
=> (string?)key[RelationalAnnotationNames.Name]
?? key.GetDefaultName(storeObject);
@@ -42,7 +42,7 @@ public static class RelationalKeyExtensions
///
/// The key.
/// The default key constraint name that would be used for this key.
- public static string GetDefaultName([NotNull] this IKey key)
+ public static string GetDefaultName([NotNull] this IReadOnlyKey key)
{
var tableName = key.DeclaringEntityType.GetTableName();
var name = key.IsPrimaryKey()
@@ -63,7 +63,7 @@ public static string GetDefaultName([NotNull] this IKey key)
/// The key.
/// The identifier of the containing store object.
/// The default key constraint name that would be used for this key.
- public static string? GetDefaultName([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
+ public static string? GetDefaultName([NotNull] this IReadOnlyKey key, in StoreObjectIdentifier storeObject)
{
string? name;
if (key.IsPrimaryKey())
@@ -105,7 +105,7 @@ public static string GetDefaultName([NotNull] this IKey key)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IKey? linkedKey = null;
+ IReadOnlyKey? linkedKey = null;
foreach (var otherKey in rootKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetKeys()))
@@ -184,7 +184,8 @@ public static void SetName([NotNull] this IMutableKey key, [CanBeNull] string? n
/// The key.
/// The unique constraints to which the key is mapped.
public static IEnumerable GetMappedConstraints([NotNull] this IKey key)
- => (IEnumerable?)key.FindRuntimeAnnotationValue(RelationalAnnotationNames.UniqueConstraintMappings)
+ => (IEnumerable?)key.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.UniqueConstraintMappings)
?? Enumerable.Empty();
///
@@ -199,7 +200,7 @@ public static IEnumerable GetMappedConstraints([NotNull] this
/// The key.
/// The identifier of the containing store object.
/// The key found, or if none was found.
- public static IKey? FindSharedObjectRootKey([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
+ public static IReadOnlyKey? FindSharedObjectRootKey([NotNull] this IReadOnlyKey key, in StoreObjectIdentifier storeObject)
{
Check.NotNull(key, nameof(key));
@@ -210,7 +211,7 @@ public static IEnumerable GetMappedConstraints([NotNull] this
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IKey? linkedKey = null;
+ IReadOnlyKey? linkedKey = null;
foreach (var otherKey in rootKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetKeys()))
diff --git a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs
index d50758ca98d..fe1f413bfc0 100644
--- a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs
@@ -18,7 +18,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Relational-specific extension methods for and extension methods for .
+ /// Relational-specific model extension methods.
///
public static class RelationalModelExtensions
{
@@ -88,7 +88,7 @@ public static string ToDebugString(
///
/// The model to get the default schema for.
/// The default schema.
- public static string? GetDefaultSchema([NotNull] this IModel model)
+ public static string? GetDefaultSchema([NotNull] this IReadOnlyModel model)
=> (string?)Check.NotNull(model, nameof(model))[RelationalAnnotationNames.DefaultSchema];
///
@@ -148,7 +148,7 @@ public static IRelationalModel GetRelationalModel([NotNull] this IModel model)
///
/// The model to get the maximum identifier length for.
/// The maximum identifier length.
- public static int GetMaxIdentifierLength([NotNull] this IModel model)
+ public static int GetMaxIdentifierLength([NotNull] this IReadOnlyModel model)
=> (int?)Check.NotNull(model, nameof(model))[RelationalAnnotationNames.MaxIdentifierLength] ?? short.MaxValue;
///
@@ -182,50 +182,69 @@ public static void SetMaxIdentifierLength([NotNull] this IMutableModel model, in
=> model.FindAnnotation(RelationalAnnotationNames.MaxIdentifierLength)?.GetConfigurationSource();
///
- /// Finds an with the given name.
+ /// Finds a sequence with the given name.
///
/// The model to find the sequence in.
/// The sequence name.
/// The schema that contains the sequence.
///
- /// The or if no sequence with the given name in
+ /// The sequence or if no sequence with the given name in
/// the given schema was found.
///
- public static ISequence? FindSequence([NotNull] this IModel model, [NotNull] string name, [CanBeNull] string? schema = null)
+ public static IReadOnlySequence? FindSequence(
+ [NotNull] this IReadOnlyModel model,
+ [NotNull] string name,
+ [CanBeNull] string? schema = null)
=> Sequence.FindSequence(
Check.NotNull(model, nameof(model)), Check.NotEmpty(name, nameof(name)), Check.NullButNotEmpty(schema, nameof(schema)));
///
- /// Finds an with the given name.
+ /// Finds a sequence with the given name.
///
/// The model to find the sequence in.
/// The sequence name.
/// The schema that contains the sequence.
///
- /// The or if no sequence with the given name in
+ /// The sequence or if no sequence with the given name in
/// the given schema was found.
///
public static IMutableSequence? FindSequence(
[NotNull] this IMutableModel model,
[NotNull] string name,
[CanBeNull] string? schema = null)
- => (IMutableSequence?)((IModel)model).FindSequence(name, schema);
+ => (IMutableSequence?)((IReadOnlyModel)model).FindSequence(name, schema);
///
- /// Finds an with the given name.
+ /// Finds a sequence with the given name.
///
/// The model to find the sequence in.
/// The sequence name.
/// The schema that contains the sequence.
///
- /// The or if no sequence with the given name in
+ /// The sequence or if no sequence with the given name in
/// the given schema was found.
///
public static IConventionSequence? FindSequence(
[NotNull] this IConventionModel model,
[NotNull] string name,
[CanBeNull] string? schema = null)
- => (IConventionSequence?)((IModel)model).FindSequence(name, schema);
+ => (IConventionSequence?)((IReadOnlyModel)model).FindSequence(name, schema);
+
+ ///
+ /// Finds a sequence with the given name.
+ ///
+ /// The model to find the sequence in.
+ /// The sequence name.
+ /// The schema that contains the sequence.
+ ///
+ /// The sequence or if no sequence with the given name in
+ /// the given schema was found.
+ ///
+ public static ISequence? FindSequence(
+ [NotNull] this IModel model,
+ [NotNull] string name,
+ [CanBeNull] string? schema = null)
+ => (ISequence?)((IReadOnlyModel)model).FindSequence(name, schema);
///
/// Either returns the existing with the given name in the given schema
@@ -292,84 +311,109 @@ public static IMutableSequence AddSequence(
=> Sequence.RemoveSequence((IMutableModel)Check.NotNull(model, nameof(model)), name, schema);
///
- /// Returns all s contained in the model.
+ /// Returns all sequences contained in the model.
///
/// The model to get the sequences in.
public static IEnumerable GetSequences([NotNull] this IModel model)
=> Sequence.GetSequences(Check.NotNull(model, nameof(model)));
///
- /// Returns all s contained in the model.
+ /// Returns all sequences contained in the model.
///
/// The model to get the sequences in.
public static IEnumerable GetSequences([NotNull] this IMutableModel model)
=> Sequence.GetSequences(Check.NotNull(model, nameof(model)));
///
- /// Returns all s contained in the model.
+ /// Returns all sequences contained in the model.
///
/// The model to get the sequences in.
public static IEnumerable GetSequences([NotNull] this IConventionModel model)
=> Sequence.GetSequences(Check.NotNull(model, nameof(model)));
///
- /// Finds a that is mapped to the method represented by the given .
+ /// Returns all sequences contained in the model.
+ ///
+ /// The model to get the sequences in.
+ public static IEnumerable GetSequences([NotNull] this IReadOnlyModel model)
+ => Sequence.GetSequences(Check.NotNull(model, nameof(model)));
+
+ ///
+ /// Finds a function that is mapped to the method represented by the given .
///
/// The model to find the function in.
/// The for the method that is mapped to the function.
- /// The or if the method is not mapped.
- public static IDbFunction? FindDbFunction([NotNull] this IModel model, [NotNull] MethodInfo method)
+ /// The function or if the method is not mapped.
+ public static IReadOnlyDbFunction? FindDbFunction([NotNull] this IReadOnlyModel model, [NotNull] MethodInfo method)
=> DbFunction.FindDbFunction(
Check.NotNull(model, nameof(model)),
Check.NotNull(method, nameof(method)));
///
- /// Finds a that is mapped to the method represented by the given .
+ /// Finds a function that is mapped to the method represented by the given .
///
/// The model to find the function in.
/// The for the method that is mapped to the function.
- /// The or if the method is not mapped.
+ /// The function or if the method is not mapped.
public static IMutableDbFunction? FindDbFunction([NotNull] this IMutableModel model, [NotNull] MethodInfo method)
- => (IMutableDbFunction?)((IModel)model).FindDbFunction(method);
+ => (IMutableDbFunction?)((IReadOnlyModel)model).FindDbFunction(method);
///
- /// Finds a that is mapped to the method represented by the given .
+ /// Finds a function that is mapped to the method represented by the given .
///
/// The model to find the function in.
/// The for the method that is mapped to the function.
- /// The or if the method is not mapped.
+ /// The function or if the method is not mapped.
public static IConventionDbFunction? FindDbFunction([NotNull] this IConventionModel model, [NotNull] MethodInfo method)
- => (IConventionDbFunction?)((IModel)model).FindDbFunction(method);
+ => (IConventionDbFunction?)((IReadOnlyModel)model).FindDbFunction(method);
///
- /// Finds an that is mapped to the method represented by the given name.
+ /// Finds a function that is mapped to the method represented by the given .
+ ///
+ /// The model to find the function in.
+ /// The for the method that is mapped to the function.
+ /// The function or if the method is not mapped.
+ public static IDbFunction? FindDbFunction([NotNull] this IModel model, [NotNull] MethodInfo method)
+ => (IDbFunction?)((IReadOnlyModel)model).FindDbFunction(method);
+
+ ///
+ /// Finds a function that is mapped to the method represented by the given name.
///
/// The model to find the function in.
/// The model name of the function.
- /// The or if the method is not mapped.
- public static IDbFunction? FindDbFunction([NotNull] this IModel model, [NotNull] string name)
+ /// The function or if the method is not mapped.
+ public static IReadOnlyDbFunction? FindDbFunction([NotNull] this IReadOnlyModel model, [NotNull] string name)
=> DbFunction.FindDbFunction(
Check.NotNull(model, nameof(model)),
Check.NotNull(name, nameof(name)));
///
- /// Finds an that is mapped to the method represented by the given name.
+ /// Finds a function that is mapped to the method represented by the given name.
///
/// The model to find the function in.
/// The model name of the function.
- /// The or if the method is not mapped.
+ /// The function or if the method is not mapped.
public static IMutableDbFunction? FindDbFunction([NotNull] this IMutableModel model, [NotNull] string name)
=> (IMutableDbFunction?)((IModel)model).FindDbFunction(name);
///
- /// Finds an that is mapped to the method represented by the given name.
+ /// Finds a function that is mapped to the method represented by the given name.
///
/// The model to find the function in.
/// The model name of the function.
- /// The or if the method is not mapped.
+ /// The function or if the method is not mapped.
public static IConventionDbFunction? FindDbFunction([NotNull] this IConventionModel model, [NotNull] string name)
=> (IConventionDbFunction?)((IModel)model).FindDbFunction(name);
+ ///
+ /// Finds a function that is mapped to the method represented by the given name.
+ ///
+ /// The model to find the function in.
+ /// The model name of the function.
+ /// The function or if the method is not mapped.
+ public static IDbFunction? FindDbFunction([NotNull] this IModel model, [NotNull] string name)
+ => (IDbFunction?)((IReadOnlyModel)model).FindDbFunction(name);
+
///
/// Creates an mapped to the given method.
///
@@ -381,12 +425,12 @@ public static IMutableDbFunction AddDbFunction([NotNull] this IMutableModel mode
model, Check.NotNull(methodInfo, nameof(methodInfo)), ConfigurationSource.Explicit)!;
///
- /// Creates an mapped to the given method.
+ /// Creates a function mapped to the given method.
///
/// The model to add the function to.
/// The for the method that is mapped to the function.
/// Indicates whether the configuration was specified using a data annotation.
- /// The new .
+ /// The new function.
public static IConventionDbFunction AddDbFunction(
[NotNull] this IConventionModel model,
[NotNull] MethodInfo methodInfo,
@@ -396,12 +440,12 @@ public static IConventionDbFunction AddDbFunction(
fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- /// Creates an .
+ /// Creates a function.
///
/// The model to add the function to.
/// The model name of the function.
/// The function return type.
- /// The new .
+ /// The new function.
public static IMutableDbFunction AddDbFunction(
[NotNull] this IMutableModel model,
[NotNull] string name,
@@ -410,13 +454,13 @@ public static IMutableDbFunction AddDbFunction(
model, Check.NotNull(name, nameof(name)), returnType, ConfigurationSource.Explicit);
///
- /// Creates an .
+ /// Creates a function.
///
/// The model to add the function to.
/// The model name of the function.
/// The function return type.
/// Indicates whether the configuration was specified using a data annotation.
- /// The new .
+ /// The new function.
public static IConventionDbFunction AddDbFunction(
[NotNull] this IConventionModel model,
[NotNull] string name,
@@ -429,76 +473,83 @@ public static IConventionDbFunction AddDbFunction(
fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- /// Removes the that is mapped to the method represented by the given
+ /// Removes the function that is mapped to the method represented by the given
/// .
///
/// The model to find the function in.
/// The for the method that is mapped to the function.
- /// The removed or if the method is not mapped.
+ /// The removed function or if the method is not mapped.
public static IMutableDbFunction? RemoveDbFunction([NotNull] this IMutableModel model, [NotNull] MethodInfo method)
=> DbFunction.RemoveDbFunction(
Check.NotNull(model, nameof(model)),
Check.NotNull(method, nameof(method)));
///
- /// Removes the that is mapped to the method represented by the given
+ /// Removes the function that is mapped to the method represented by the given
/// .
///
/// The model to find the function in.
/// The for the method that is mapped to the function.
- /// The removed or if the method is not mapped.
+ /// The removed function or if the method is not mapped.
public static IConventionDbFunction? RemoveDbFunction([NotNull] this IConventionModel model, [NotNull] MethodInfo method)
=> (IConventionDbFunction?)((IMutableModel)model).RemoveDbFunction(method);
///
- /// Removes the that is mapped to the method represented by the given
+ /// Removes the function that is mapped to the method represented by the given
/// .
///
/// The model to find the function in.
/// The model name of the function.
- /// The removed or if the method is not mapped.
+ /// The removed function or if the method is not mapped.
public static IMutableDbFunction? RemoveDbFunction([NotNull] this IMutableModel model, [NotNull] string name)
=> DbFunction.RemoveDbFunction(
Check.NotNull(model, nameof(model)),
Check.NotNull(name, nameof(name)));
///
- /// Removes the that is mapped to the method represented by the given
+ /// Removes the function that is mapped to the method represented by the given
/// .
///
/// The model to find the function in.
/// The model name of the function.
- /// The removed or if the method is not mapped.
+ /// The removed function or if the method is not mapped.
public static IConventionDbFunction? RemoveDbFunction([NotNull] this IConventionModel model, [NotNull] string name)
=> (IConventionDbFunction?)((IMutableModel)model).RemoveDbFunction(name);
///
- /// Returns all s contained in the model.
+ /// Returns all functions contained in the model.
///
/// The model to get the functions in.
- public static IEnumerable GetDbFunctions([NotNull] this IModel model)
+ public static IEnumerable GetDbFunctions([NotNull] this IModel model)
=> DbFunction.GetDbFunctions(Check.NotNull(model, nameof(model)));
///
- /// Returns all s contained in the model.
+ /// Returns all functions contained in the model.
///
/// The model to get the functions in.
public static IEnumerable GetDbFunctions([NotNull] this IMutableModel model)
=> DbFunction.GetDbFunctions((Model)Check.NotNull(model, nameof(model)));
///
- /// Returns all s contained in the model.
+ /// Returns all functions contained in the model.
///
/// The model to get the functions in.
public static IEnumerable GetDbFunctions([NotNull] this IConventionModel model)
=> DbFunction.GetDbFunctions((Model)Check.NotNull(model, nameof(model)));
+ ///
+ /// Returns all functions contained in the model.
+ ///
+ /// The model to get the functions in.
+ public static IEnumerable GetDbFunctions([NotNull] this IReadOnlyModel model)
+ => DbFunction.GetDbFunctions((Model)Check.NotNull(model, nameof(model)));
+
///
/// Returns the database collation.
///
/// The model to get the collation for.
/// The collation.
- public static string? GetCollation([NotNull] this IModel model)
+ public static string? GetCollation([NotNull] this IReadOnlyModel model)
=> (string?)model[RelationalAnnotationNames.Collation];
///
diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
index fac0596b325..493d0a8231e 100644
--- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
@@ -21,7 +21,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for relational database metadata.
+ /// Property extension methods for relational database metadata.
///
public static class RelationalPropertyExtensions
{
@@ -39,7 +39,7 @@ public static string GetColumnName([NotNull] this IProperty property)
///
/// The property.
/// The the base name of the column to which the property would be mapped.
- public static string GetColumnBaseName([NotNull] this IProperty property)
+ public static string GetColumnBaseName([NotNull] this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.ColumnName)?.Value ?? property.GetDefaultColumnBaseName();
///
@@ -48,7 +48,7 @@ public static string GetColumnBaseName([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The name of the column to which the property is mapped.
- public static string? GetColumnName([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetColumnName([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -110,7 +110,7 @@ public static string GetDefaultColumnName([NotNull] this IProperty property)
///
/// The property.
/// The default base column name to which the property would be mapped.
- public static string GetDefaultColumnBaseName([NotNull] this IProperty property)
+ public static string GetDefaultColumnBaseName([NotNull] this IReadOnlyProperty property)
=> Uniquifier.Truncate(property.Name, property.DeclaringEntityType.Model.GetMaxIdentifierLength());
///
@@ -119,7 +119,7 @@ public static string GetDefaultColumnBaseName([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The default column name to which the property would be mapped.
- public static string GetDefaultColumnName([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string GetDefaultColumnName([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var sharedTablePrincipalPrimaryKeyProperty = FindSharedObjectRootPrimaryKeyProperty(property, storeObject);
if (sharedTablePrincipalPrimaryKeyProperty != null)
@@ -285,7 +285,7 @@ public static void SetColumnName(
///
/// The property.
/// The database type of the column to which the property is mapped.
- public static string? GetColumnType([NotNull] this IProperty property)
+ public static string? GetColumnType([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -299,7 +299,7 @@ public static void SetColumnName(
/// The property.
/// The identifier of the table-like store object containing the column.
/// The database type of the column to which the property is mapped.
- public static string? GetColumnType([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetColumnType([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.ColumnType);
if (annotation != null)
@@ -310,7 +310,7 @@ public static void SetColumnName(
return GetDefaultColumnType(property, storeObject);
}
- private static string? GetDefaultColumnType(IProperty property, in StoreObjectIdentifier storeObject)
+ private static string? GetDefaultColumnType(IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject);
return sharedTableRootProperty != null
@@ -362,7 +362,8 @@ public static void SetColumnType([NotNull] this IMutableProperty property, [CanB
/// The property.
/// The default columns to which the property would be mapped.
public static IEnumerable GetDefaultColumnMappings([NotNull] this IProperty property)
- => (IEnumerable?)property.FindRuntimeAnnotationValue(RelationalAnnotationNames.DefaultColumnMappings)
+ => (IEnumerable?)property.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.DefaultColumnMappings)
?? Enumerable.Empty();
///
@@ -371,7 +372,8 @@ public static IEnumerable GetDefaultColumnMappings([NotNull]
/// The property.
/// The table columns to which the property is mapped.
public static IEnumerable GetTableColumnMappings([NotNull] this IProperty property)
- => (IEnumerable?)property.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableColumnMappings)
+ => (IEnumerable?)property.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.TableColumnMappings)
?? Enumerable.Empty();
///
@@ -380,7 +382,8 @@ public static IEnumerable GetTableColumnMappings([NotNull] this
/// The property.
/// The view columns to which the property is mapped.
public static IEnumerable GetViewColumnMappings([NotNull] this IProperty property)
- => (IEnumerable?)property.FindRuntimeAnnotationValue(RelationalAnnotationNames.ViewColumnMappings)
+ => (IEnumerable?)property.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.ViewColumnMappings)
?? Enumerable.Empty();
///
@@ -389,7 +392,8 @@ public static IEnumerable GetViewColumnMappings([NotNull] th
/// The property.
/// The SQL query columns to which the property is mapped.
public static IEnumerable GetSqlQueryColumnMappings([NotNull] this IProperty property)
- => (IEnumerable?)property.FindRuntimeAnnotationValue(RelationalAnnotationNames.SqlQueryColumnMappings)
+ => (IEnumerable?)property.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.SqlQueryColumnMappings)
?? Enumerable.Empty();
///
@@ -398,7 +402,8 @@ public static IEnumerable GetSqlQueryColumnMappings([Not
/// The property.
/// The function columns to which the property is mapped.
public static IEnumerable GetFunctionColumnMappings([NotNull] this IProperty property)
- => (IEnumerable?)property.FindRuntimeAnnotationValue(RelationalAnnotationNames.FunctionColumnMappings)
+ => (IEnumerable?)property.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.FunctionColumnMappings)
?? Enumerable.Empty();
///
@@ -461,7 +466,7 @@ public static IEnumerable GetFunctionColumnMappings([Not
///
/// The property.
/// The SQL expression that is used as the default value for the column this property is mapped to.
- public static string? GetDefaultValueSql([NotNull] this IProperty property)
+ public static string? GetDefaultValueSql([NotNull] this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.DefaultValueSql)?.Value;
///
@@ -470,7 +475,7 @@ public static IEnumerable GetFunctionColumnMappings([Not
/// The property.
/// The identifier of the table-like store object containing the column.
/// The SQL expression that is used as the default value for the column this property is mapped to.
- public static string? GetDefaultValueSql([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetDefaultValueSql([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.DefaultValueSql);
if (annotation != null)
@@ -530,7 +535,7 @@ public static void SetDefaultValueSql([NotNull] this IMutableProperty property,
///
/// The property.
/// The SQL expression that is used as the computed value for the column this property is mapped to.
- public static string? GetComputedColumnSql([NotNull] this IProperty property)
+ public static string? GetComputedColumnSql([NotNull] this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.ComputedColumnSql)?.Value;
///
@@ -539,7 +544,7 @@ public static void SetDefaultValueSql([NotNull] this IMutableProperty property,
/// The property.
/// The identifier of the table-like store object containing the column.
/// The SQL expression that is used as the computed value for the column this property is mapped to.
- public static string? GetComputedColumnSql([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetComputedColumnSql([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.ComputedColumnSql);
if (annotation != null)
@@ -603,7 +608,7 @@ public static void SetComputedColumnSql([NotNull] this IMutableProperty property
/// Whether the value of the computed column this property is mapped to is stored in the database,
/// or calculated when it is read.
///
- public static bool? GetIsStored([NotNull] this IProperty property)
+ public static bool? GetIsStored([NotNull] this IReadOnlyProperty property)
=> (bool?)property.FindAnnotation(RelationalAnnotationNames.IsStored)?.Value;
///
@@ -616,7 +621,7 @@ public static void SetComputedColumnSql([NotNull] this IMutableProperty property
/// Whether the value of the computed column this property is mapped to is stored in the database,
/// or calculated when it is read.
///
- public static bool? GetIsStored([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static bool? GetIsStored([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.IsStored);
if (annotation != null)
@@ -673,7 +678,7 @@ public static void SetIsStored([NotNull] this IMutableProperty property, bool? v
///
/// The property.
/// The object that is used as the default value for the column this property is mapped to.
- public static object? GetDefaultValue([NotNull] this IProperty property)
+ public static object? GetDefaultValue([NotNull] this IReadOnlyProperty property)
=> property.FindAnnotation(RelationalAnnotationNames.DefaultValue)?.Value;
///
@@ -682,7 +687,7 @@ public static void SetIsStored([NotNull] this IMutableProperty property, bool? v
/// The property.
/// The identifier of the table-like store object containing the column.
/// The object that is used as the default value for the column this property is mapped to.
- public static object? GetDefaultValue([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static object? GetDefaultValue([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.DefaultValue);
if (annotation != null)
@@ -725,7 +730,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
return value;
}
- private static object? ConvertDefaultValue([NotNull] IProperty property, [CanBeNull] object? value)
+ private static object? ConvertDefaultValue([NotNull] IReadOnlyProperty property, [CanBeNull] object? value)
{
if (value == null
|| value == DBNull.Value)
@@ -766,7 +771,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
/// The property.
/// The identifier of the table-like store object containing the column.
/// The maximum length, or if none if defined.
- public static int? GetMaxLength([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static int? GetMaxLength([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -787,7 +792,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
/// The property.
/// The identifier of the table-like store object containing the column.
/// The precision, or if none is defined.
- public static int? GetPrecision([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static int? GetPrecision([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -808,7 +813,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
/// The property.
/// The identifier of the table-like store object containing the column.
/// The scale, or if none is defined.
- public static int? GetScale([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static int? GetScale([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -828,7 +833,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
/// The property.
/// The identifier of the table-like store object containing the column.
/// The Unicode setting, or if none is defined.
- public static bool? IsUnicode([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static bool? IsUnicode([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -847,7 +852,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
///
/// The property.
/// A flag indicating if the property as capable of storing only fixed-length data, such as strings.
- public static bool? IsFixedLength([NotNull] this IProperty property)
+ public static bool? IsFixedLength([NotNull] this IReadOnlyProperty property)
=> (bool?)property.FindAnnotation(RelationalAnnotationNames.IsFixedLength)?.Value;
///
@@ -856,7 +861,7 @@ public static void SetDefaultValue([NotNull] this IMutableProperty property, [Ca
/// The property.
/// The identifier of the table-like store object containing the column.
/// A flag indicating if the property as capable of storing only fixed-length data, such as strings.
- public static bool? IsFixedLength([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static bool? IsFixedLength([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.IsFixedLength);
if (annotation != null)
@@ -899,10 +904,10 @@ public static void SetIsFixedLength([NotNull] this IMutableProperty property, bo
}
///
- /// Gets the for .
+ /// Gets the for .
///
/// The property.
- /// The for .
+ /// The for .
public static ConfigurationSource? GetIsFixedLengthConfigurationSource([NotNull] this IConventionProperty property)
=> property.FindAnnotation(RelationalAnnotationNames.IsFixedLength)?.GetConfigurationSource();
@@ -917,15 +922,15 @@ public static void SetIsFixedLength([NotNull] this IMutableProperty property, bo
/// As well as properties on optional types sharing the same table.
///
///
- /// The .
+ /// The .
/// if the mapped column is nullable; otherwise.
- public static bool IsColumnNullable([NotNull] this IProperty property)
+ public static bool IsColumnNullable([NotNull] this IReadOnlyProperty property)
=> property.IsNullable
|| (property.DeclaringEntityType.BaseType != null && property.DeclaringEntityType.GetDiscriminatorProperty() != null);
///
///
- /// Checks whether the column mapped to the given will be nullable
+ /// Checks whether the column mapped to the given property will be nullable
/// when created in the database.
///
///
@@ -934,10 +939,10 @@ public static bool IsColumnNullable([NotNull] this IProperty property)
/// As well as properties on optional types sharing the same table.
///
///
- /// The .
+ /// The property.
/// The identifier of the table-like store object containing the column.
/// if the mapped column is nullable; otherwise.
- public static bool IsColumnNullable([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static bool IsColumnNullable([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
if (property.IsPrimaryKey())
{
@@ -955,7 +960,7 @@ public static bool IsColumnNullable([NotNull] this IProperty property, in StoreO
|| IsOptionalSharingDependent(property.DeclaringEntityType, storeObject, 0);
}
- private static bool IsOptionalSharingDependent(IEntityType entityType, in StoreObjectIdentifier storeObject, int recursionDepth)
+ private static bool IsOptionalSharingDependent(IReadOnlyEntityType entityType, in StoreObjectIdentifier storeObject, int recursionDepth)
{
if (recursionDepth++ == Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable)
{
@@ -978,7 +983,7 @@ private static bool IsOptionalSharingDependent(IEntityType entityType, in StoreO
///
/// The property.
/// The comment for the column this property is mapped to.
- public static string? GetComment([NotNull] this IProperty property)
+ public static string? GetComment([NotNull] this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.Comment)?.Value;
///
@@ -987,7 +992,7 @@ private static bool IsOptionalSharingDependent(IEntityType entityType, in StoreO
/// The property.
/// The identifier of the table-like store object containing the column.
/// The comment for the column this property is mapped to.
- public static string? GetComment([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetComment([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.Comment);
if (annotation != null)
@@ -1043,7 +1048,7 @@ public static void SetComment([NotNull] this IMutableProperty property, [CanBeNu
///
/// The property.
/// The collation for the column this property is mapped to.
- public static string? GetCollation([NotNull] this IProperty property)
+ public static string? GetCollation([NotNull] this IReadOnlyProperty property)
=> (string?)property.FindAnnotation(RelationalAnnotationNames.Collation)?.Value;
///
@@ -1052,7 +1057,7 @@ public static void SetComment([NotNull] this IMutableProperty property, [CanBeNu
/// The property.
/// The identifier of the table-like store object containing the column.
/// The collation for the column this property is mapped to.
- public static string? GetCollation([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetCollation([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.Collation);
if (annotation != null)
@@ -1107,7 +1112,7 @@ public static void SetCollation([NotNull] this IMutableProperty property, [CanBe
/// The property.
/// The type mapping.
[DebuggerStepThrough]
- public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IProperty property)
+ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IReadOnlyProperty property)
=> (RelationalTypeMapping)property.GetTypeMapping();
///
@@ -1126,7 +1131,7 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
/// The property.
/// The type mapping, or if none was found.
[DebuggerStepThrough]
- public static RelationalTypeMapping? FindRelationalTypeMapping([NotNull] this IProperty property)
+ public static RelationalTypeMapping? FindRelationalTypeMapping([NotNull] this IReadOnlyProperty property)
=> (RelationalTypeMapping?)property.FindTypeMapping();
///
@@ -1136,7 +1141,7 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
/// The identifier of the table-like store object containing the column.
/// The type mapping, or if none was found.
public static RelationalTypeMapping? FindRelationalTypeMapping(
- [NotNull] this IProperty property,
+ [NotNull] this IReadOnlyProperty property,
in StoreObjectIdentifier storeObject)
=> property.FindRelationalTypeMapping();
@@ -1152,8 +1157,8 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
/// The property.
/// The identifier of the table-like store object containing the column.
/// The property found, or if none was found.
- public static IProperty? FindSharedStoreObjectRootProperty(
- [NotNull] this IProperty property,
+ public static IReadOnlyProperty? FindSharedStoreObjectRootProperty(
+ [NotNull] this IReadOnlyProperty property,
in StoreObjectIdentifier storeObject)
=> FindSharedObjectRootProperty(property, storeObject);
@@ -1191,7 +1196,7 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
in StoreObjectIdentifier storeObject)
=> (IConventionProperty?)FindSharedObjectRootProperty(property, storeObject);
- private static IProperty? FindSharedObjectRootProperty([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
+ private static IReadOnlyProperty? FindSharedObjectRootProperty([NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -1210,7 +1215,7 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- IProperty? linkedProperty = null;
+ IReadOnlyProperty? linkedProperty = null;
foreach (var p in rootProperty.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
.SelectMany(fk => fk.PrincipalEntityType.GetProperties()))
@@ -1233,7 +1238,8 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
return rootProperty == property ? null : rootProperty;
}
- private static IProperty? FindSharedObjectRootPrimaryKeyProperty([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
+ private static IReadOnlyProperty? FindSharedObjectRootPrimaryKeyProperty(
+ [NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
if (!property.IsPrimaryKey())
{
@@ -1259,8 +1265,8 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
return principalProperty == property ? null : principalProperty;
}
- private static IProperty? FindSharedObjectRootConcurrencyTokenProperty(
- [NotNull] IProperty property,
+ private static IReadOnlyProperty? FindSharedObjectRootConcurrencyTokenProperty(
+ [NotNull] IReadOnlyProperty property,
in StoreObjectIdentifier storeObject)
{
if (!property.IsConcurrencyToken)
@@ -1291,6 +1297,21 @@ public static RelationalTypeMapping GetRelationalTypeMapping([NotNull] this IPro
return principalProperty == property ? null : principalProperty;
}
+ ///
+ ///
+ /// Returns the property facet overrides for a particular table-like store object.
+ ///
+ ///
+ /// This method is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// The property.
+ /// The identifier of the table-like store object containing the column.
+ /// An object that stores property facet overrides.
+ public static IReadOnlyAnnotatable? FindOverrides([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
+ => RelationalPropertyOverrides.Find(property, storeObject);
+
///
///
/// Returns the property facet overrides for a particular table-like store object.
diff --git a/src/EFCore.Relational/Infrastructure/ModelSnapshot.cs b/src/EFCore.Relational/Infrastructure/ModelSnapshot.cs
index 3e04b5ea2fb..f6e3ecb4d40 100644
--- a/src/EFCore.Relational/Infrastructure/ModelSnapshot.cs
+++ b/src/EFCore.Relational/Infrastructure/ModelSnapshot.cs
@@ -19,7 +19,7 @@ private IModel CreateModel()
BuildModel(modelBuilder);
- return modelBuilder.Model;
+ return (IModel)modelBuilder.Model;
}
///
diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs b/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs
index a3724518fa0..202a4e3fa09 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalModelRuntimeInitializer.cs
@@ -63,7 +63,7 @@ protected override void InitializeModel(IModel model, bool preValidation)
}
else
{
- RelationalModel.Add((IConventionModel)model, RelationalDependencies.RelationalAnnotationProvider);
+ RelationalModel.Add(model, RelationalDependencies.RelationalAnnotationProvider);
}
}
}
diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
index fe765fb5ccf..54668c56697 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
@@ -249,13 +249,13 @@ protected virtual void ValidateDefaultValuesOnKeys(
[NotNull] IModel model,
[NotNull] IDiagnosticsLogger logger)
{
- foreach (var entityType in ((IConventionModel)model).GetEntityTypes())
+ foreach (var entityType in model.GetEntityTypes())
{
foreach (var key in entityType.GetDeclaredKeys())
{
foreach (var property in key.Properties)
{
- var defaultValue = property.FindAnnotation(RelationalAnnotationNames.DefaultValue);
+ var defaultValue = (IConventionAnnotation)property.FindAnnotation(RelationalAnnotationNames.DefaultValue);
if (defaultValue?.Value != null
&& defaultValue.GetConfigurationSource().Overrides(ConfigurationSource.DataAnnotation))
{
diff --git a/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
index d0a35964017..dafbc5e18fb 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
@@ -22,7 +22,7 @@ public static class RelationalPropertyExtensions
/// The identifier of the table-like store object containing the column.
/// A comma-separated list of column names.
public static string FormatColumns(
- [NotNull] this IEnumerable properties,
+ [NotNull] this IEnumerable properties,
StoreObjectIdentifier storeObject)
=> "{" + string.Join(", ", properties.Select(p => "'" + p.GetColumnName(storeObject) + "'")) + "}";
@@ -33,7 +33,7 @@ public static string FormatColumns(
/// The identifier of the table-like store object containing the column.
/// A list of column names.
public static IReadOnlyList? GetColumnNames(
- [NotNull] this IEnumerable properties,
+ [NotNull] this IEnumerable properties,
in StoreObjectIdentifier storeObject)
{
var propertyNames = new List();
diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalModelConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalModelConvention.cs
index f65bb333161..9af8b96d1c5 100644
--- a/src/EFCore.Relational/Metadata/Conventions/RelationalModelConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/RelationalModelConvention.cs
@@ -35,8 +35,6 @@ public RelationalModelConvention(
///
public virtual IModel ProcessModelFinalized(IModel model)
- => model is IConventionModel conventionModel
- ? RelationalModel.Add(conventionModel, RelationalDependencies.RelationalAnnotationProvider)
- : model;
+ => RelationalModel.Add(model, RelationalDependencies.RelationalAnnotationProvider);
}
}
diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
index a2be599a241..011a8de2c77 100644
--- a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
@@ -150,7 +150,7 @@ private void ProcessTableChanged(
/// The property.
/// The identifier of the store object.
/// The new store value generation strategy to set for the given property.
- public static ValueGenerated? GetValueGenerated([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
+ public static ValueGenerated? GetValueGenerated([NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var valueGenerated = GetValueGenerated(property);
return valueGenerated
diff --git a/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
index b4531f39857..a56aedeada5 100644
--- a/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
@@ -304,8 +304,8 @@ private void TryUniquifyKeyNames(
/// The identifier of the store object.
/// if compatible
protected virtual bool AreCompatible(
- [NotNull] IKey key,
- [NotNull] IKey duplicateKey,
+ [NotNull] IReadOnlyKey key,
+ [NotNull] IReadOnlyKey duplicateKey,
in StoreObjectIdentifier storeObject)
=> key.AreCompatible(duplicateKey, storeObject, shouldThrow: false);
@@ -374,8 +374,8 @@ private void TryUniquifyIndexNames(
/// The identifier of the store object.
/// if compatible
protected virtual bool AreCompatible(
- [NotNull] IIndex index,
- [NotNull] IIndex duplicateIndex,
+ [NotNull] IReadOnlyIndex index,
+ [NotNull] IReadOnlyIndex duplicateIndex,
in StoreObjectIdentifier storeObject)
=> index.AreCompatible(duplicateIndex, storeObject, shouldThrow: false);
@@ -465,8 +465,8 @@ private void TryUniquifyForeignKeyNames(
/// The identifier of the store object.
/// if compatible
protected virtual bool AreCompatible(
- [NotNull] IForeignKey foreignKey,
- [NotNull] IForeignKey duplicateForeignKey,
+ [NotNull] IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyForeignKey duplicateForeignKey,
in StoreObjectIdentifier storeObject)
=> foreignKey.AreCompatible(duplicateForeignKey, storeObject, shouldThrow: false);
diff --git a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
index 14331c19421..68480f9c269 100644
--- a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
@@ -80,7 +80,7 @@ public virtual void ProcessModelFinalizing(
var concurrencyColumnName = concurrencyColumn.Key;
var propertiesMappedToConcurrencyColumn = concurrencyColumn.Value;
- Dictionary? entityTypesMissingConcurrencyColumn = null;
+ Dictionary? entityTypesMissingConcurrencyColumn = null;
foreach (var entityType in mappedTypes)
{
var foundMappedProperty = !IsConcurrencyTokenMissing(propertiesMappedToConcurrencyColumn, entityType, mappedTypes)
@@ -91,7 +91,7 @@ public virtual void ProcessModelFinalizing(
{
if (entityTypesMissingConcurrencyColumn == null)
{
- entityTypesMissingConcurrencyColumn = new Dictionary();
+ entityTypesMissingConcurrencyColumn = new Dictionary();
}
// store the entity type which is missing the
@@ -133,16 +133,16 @@ public virtual void ProcessModelFinalizing(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[EntityFrameworkInternal]
- public static Dictionary>? GetConcurrencyTokensMap(
+ public static Dictionary>? GetConcurrencyTokensMap(
in StoreObjectIdentifier storeObject,
- [NotNull] IReadOnlyList mappedTypes)
+ [NotNull] IReadOnlyList mappedTypes)
{
if (mappedTypes.Count < 2)
{
return null;
}
- Dictionary>? concurrencyColumns = null;
+ Dictionary>? concurrencyColumns = null;
var nonHierarchyTypesCount = 0;
foreach (var entityType in mappedTypes)
{
@@ -168,12 +168,12 @@ public virtual void ProcessModelFinalizing(
if (concurrencyColumns == null)
{
- concurrencyColumns = new Dictionary>();
+ concurrencyColumns = new Dictionary>();
}
if (!concurrencyColumns.TryGetValue(columnName, out var properties))
{
- properties = new List();
+ properties = new List();
concurrencyColumns[columnName] = properties;
}
@@ -192,9 +192,9 @@ public virtual void ProcessModelFinalizing(
///
[EntityFrameworkInternal]
public static bool IsConcurrencyTokenMissing(
- [NotNull] List propertiesMappedToConcurrencyColumn,
- [NotNull] IEntityType entityType,
- [NotNull] IReadOnlyList mappedTypes)
+ [NotNull] List propertiesMappedToConcurrencyColumn,
+ [NotNull] IReadOnlyEntityType entityType,
+ [NotNull] IReadOnlyList mappedTypes)
{
if (entityType.FindPrimaryKey() == null)
{
diff --git a/src/EFCore.Relational/Metadata/DbFunctionExtensions.cs b/src/EFCore.Relational/Metadata/DbFunctionExtensions.cs
index d0fee4979f8..7b2c85b1fb2 100644
--- a/src/EFCore.Relational/Metadata/DbFunctionExtensions.cs
+++ b/src/EFCore.Relational/Metadata/DbFunctionExtensions.cs
@@ -11,7 +11,7 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class DbFunctionExtensions
{
@@ -29,7 +29,7 @@ public static class DbFunctionExtensions
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IDbFunction function,
+ [NotNull] this IReadOnlyDbFunction function,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore.Relational/Metadata/DbFunctionParameterExtensions.cs b/src/EFCore.Relational/Metadata/DbFunctionParameterExtensions.cs
index 32a47ff3e65..43d77e6c403 100644
--- a/src/EFCore.Relational/Metadata/DbFunctionParameterExtensions.cs
+++ b/src/EFCore.Relational/Metadata/DbFunctionParameterExtensions.cs
@@ -10,7 +10,7 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class DbFunctionParameterExtensions
{
@@ -28,7 +28,7 @@ public static class DbFunctionParameterExtensions
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IDbFunctionParameter parameter,
+ [NotNull] this IReadOnlyDbFunctionParameter parameter,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore.Relational/Metadata/ICheckConstraint.cs b/src/EFCore.Relational/Metadata/ICheckConstraint.cs
index ec161778d92..9551015debd 100644
--- a/src/EFCore.Relational/Metadata/ICheckConstraint.cs
+++ b/src/EFCore.Relational/Metadata/ICheckConstraint.cs
@@ -10,21 +10,11 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a check constraint in the .
///
- public interface ICheckConstraint : IAnnotatable
+ public interface ICheckConstraint : IReadOnlyCheckConstraint, IAnnotatable
{
- ///
- /// Gets the name of the check constraint in the database.
- ///
- string Name { get; }
-
///
/// Gets the in which this check constraint is defined.
///
- IEntityType EntityType { get; }
-
- ///
- /// Gets the constraint sql used in a check constraint in the database.
- ///
- string Sql { get; }
+ new IEntityType EntityType { get; }
}
}
diff --git a/src/EFCore.Relational/Metadata/IConventionCheckConstraint.cs b/src/EFCore.Relational/Metadata/IConventionCheckConstraint.cs
index 25d148648fc..94f8c8edbb3 100644
--- a/src/EFCore.Relational/Metadata/IConventionCheckConstraint.cs
+++ b/src/EFCore.Relational/Metadata/IConventionCheckConstraint.cs
@@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a check constraint in the .
///
- public interface IConventionCheckConstraint : ICheckConstraint, IConventionAnnotatable
+ public interface IConventionCheckConstraint : IReadOnlyCheckConstraint, IConventionAnnotatable
{
///
/// Gets the in which this check constraint is defined.
diff --git a/src/EFCore.Relational/Metadata/IConventionDbFunction.cs b/src/EFCore.Relational/Metadata/IConventionDbFunction.cs
index 3d44c873c4c..9e250509a61 100644
--- a/src/EFCore.Relational/Metadata/IConventionDbFunction.cs
+++ b/src/EFCore.Relational/Metadata/IConventionDbFunction.cs
@@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Represents a relational database function in an in
/// the a form that can be mutated while the model is being built.
///
- public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
+ public interface IConventionDbFunction : IReadOnlyDbFunction, IConventionAnnotatable
{
///
/// Gets the in which this function is defined.
@@ -44,9 +44,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
string? SetName([CanBeNull] string? name, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetNameConfigurationSource();
///
@@ -58,9 +58,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
string? SetSchema([CanBeNull] string? schema, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetSchemaConfigurationSource();
///
@@ -72,9 +72,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
bool SetIsBuiltIn(bool builtIn, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsBuiltInConfigurationSource();
///
@@ -86,9 +86,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
bool SetIsNullable(bool nullable, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsNullableConfigurationSource();
///
@@ -100,9 +100,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
string? SetStoreType([CanBeNull] string? storeType, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetStoreTypeConfigurationSource();
///
@@ -114,9 +114,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
RelationalTypeMapping? SetTypeMapping([CanBeNull] RelationalTypeMapping? typeMapping, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetTypeMappingConfigurationSource();
///
@@ -132,9 +132,9 @@ public interface IConventionDbFunction : IConventionAnnotatable, IDbFunction
bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetTranslationConfigurationSource();
///
diff --git a/src/EFCore.Relational/Metadata/IConventionDbFunctionParameter.cs b/src/EFCore.Relational/Metadata/IConventionDbFunctionParameter.cs
index f101c6210fe..ec0d0eb4e0e 100644
--- a/src/EFCore.Relational/Metadata/IConventionDbFunctionParameter.cs
+++ b/src/EFCore.Relational/Metadata/IConventionDbFunctionParameter.cs
@@ -12,7 +12,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a parameter.
///
- public interface IConventionDbFunctionParameter : IConventionAnnotatable, IDbFunctionParameter
+ public interface IConventionDbFunctionParameter : IConventionAnnotatable, IReadOnlyDbFunctionParameter
{
///
/// The to which this parameter belongs.
@@ -38,9 +38,9 @@ public interface IConventionDbFunctionParameter : IConventionAnnotatable, IDbFun
string? SetStoreType([CanBeNull] string? storeType, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetStoreTypeConfigurationSource();
///
@@ -51,9 +51,9 @@ public interface IConventionDbFunctionParameter : IConventionAnnotatable, IDbFun
RelationalTypeMapping? SetTypeMapping([CanBeNull] RelationalTypeMapping? typeMapping, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetTypeMappingConfigurationSource();
}
}
diff --git a/src/EFCore.Relational/Metadata/IConventionSequence.cs b/src/EFCore.Relational/Metadata/IConventionSequence.cs
index cb93b138d8c..85703b6b276 100644
--- a/src/EFCore.Relational/Metadata/IConventionSequence.cs
+++ b/src/EFCore.Relational/Metadata/IConventionSequence.cs
@@ -10,10 +10,10 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a database sequence in the in a form that
+ /// Represents a database sequence in the model in a form that
/// can be mutated while building the model.
///
- public interface IConventionSequence : ISequence, IConventionAnnotatable
+ public interface IConventionSequence : IReadOnlySequence, IConventionAnnotatable
{
///
/// Gets the in which this sequence is defined.
@@ -41,9 +41,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
long? SetStartValue(long? startValue, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetStartValueConfigurationSource();
///
@@ -55,9 +55,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
int? SetIncrementBy(int? incrementBy, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIncrementByConfigurationSource();
///
@@ -69,9 +69,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
long? SetMinValue(long? minValue, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetMinValueConfigurationSource();
///
@@ -83,9 +83,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
long? SetMaxValue(long? maxValue, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetMaxValueConfigurationSource();
///
@@ -97,9 +97,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
Type? SetType([CanBeNull] Type? type, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetTypeConfigurationSource();
///
@@ -112,9 +112,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
Type? SetClrType([CanBeNull] Type? type, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
[Obsolete("Use GetTypeConfigurationSource")]
ConfigurationSource? GetClrTypeConfigurationSource();
@@ -130,9 +130,9 @@ public interface IConventionSequence : ISequence, IConventionAnnotatable
bool? SetIsCyclic(bool? cyclic, bool fromDataAnnotation = false);
///
- /// Gets the configuration source for .
+ /// Gets the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsCyclicConfigurationSource();
}
}
diff --git a/src/EFCore.Relational/Metadata/IDbFunction.cs b/src/EFCore.Relational/Metadata/IDbFunction.cs
index 3ca10d6ef0d..68f8f10cf0d 100644
--- a/src/EFCore.Relational/Metadata/IDbFunction.cs
+++ b/src/EFCore.Relational/Metadata/IDbFunction.cs
@@ -1,93 +1,28 @@
// 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.Collections.Generic;
-using System.Reflection;
using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
-using Microsoft.EntityFrameworkCore.Storage;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a relational database function in an .
+ /// Represents a relational database function in an in
+ /// the a form that can be mutated while the model is being built.
///
- public interface IDbFunction : IAnnotatable
+ public interface IDbFunction : IReadOnlyDbFunction, IAnnotatable
{
///
- /// Gets the name of the function in the database.
+ /// Gets the model in which this function is defined.
///
- string Name { get; }
+ new IModel Model { get; }
///
- /// Gets the schema of the function in the database.
+ /// Gets the parameters for this function
///
- string? Schema { get; }
-
- ///
- /// Gets the name of the function in the model.
- ///
- string ModelName { get; }
-
- ///
- /// Gets the in which this function is defined.
- ///
- IModel Model { get; }
-
- ///
- /// Gets the CLR method which maps to the function in the database.
- ///
- MethodInfo? MethodInfo { get; }
-
- ///
- /// Gets the value indicating whether the database function is built-in.
- ///
- bool IsBuiltIn { get; }
-
- ///
- /// Gets the value indicating whether this function returns scalar value.
- ///
- [CA.MemberNotNullWhen(true, nameof(TypeMapping))]
- bool IsScalar { get; }
-
- ///
- /// Gets the value indicating whether this function is an aggregate function.
- ///
- bool IsAggregate { get; }
-
- ///
- /// Gets the value indicating whether the database function can return null.
- ///
- bool IsNullable { get; }
-
- ///
- /// Gets the configured store type string.
- ///
- string? StoreType { get; }
-
- ///
- /// Gets the returned CLR type.
- ///
- Type ReturnType { get; }
-
- ///
- /// Gets the type mapping for the function's return type.
- ///
- RelationalTypeMapping? TypeMapping { get; }
-
- ///
- /// Gets the parameters for this function.
- ///
- IReadOnlyList Parameters { get; }
-
- ///
- /// Gets the translation callback for performing custom translation of the method call into a SQL expression fragment.
- ///
- Func, SqlExpression>? Translation { get; }
+ new IReadOnlyList Parameters { get; }
///
/// Gets the associated .
diff --git a/src/EFCore.Relational/Metadata/IDbFunctionParameter.cs b/src/EFCore.Relational/Metadata/IDbFunctionParameter.cs
index 2c1b7c22adb..5a3edbc7a85 100644
--- a/src/EFCore.Relational/Metadata/IDbFunctionParameter.cs
+++ b/src/EFCore.Relational/Metadata/IDbFunctionParameter.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
@@ -10,45 +9,28 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a parameter.
+ /// Represents a function parameter.
///
- public interface IDbFunctionParameter : IAnnotatable
+ public interface IDbFunctionParameter : IReadOnlyDbFunctionParameter, IAnnotatable
{
///
- /// Gets the to which this parameter belongs.
+ /// Gets the function to which this parameter belongs.
///
- IDbFunction Function { get; }
-
- ///
- /// Gets the parameter name.
- ///
- string Name { get; }
-
- ///
- /// Gets the parameter type.
- ///
- Type ClrType { get; }
+ new IDbFunction Function { get; }
///
/// Gets the store type of this parameter.
///
- string StoreType { get; }
-
- ///
- /// Gets the value which indicates whether parameter propagates nullability, meaning if it's value is null the database function itself
- /// returns null.
- ///
- bool PropagatesNullability { get; }
+ new string StoreType { get; }
///
/// Gets the for this parameter.
///
- RelationalTypeMapping TypeMapping { get; }
+ new RelationalTypeMapping TypeMapping { get; }
///
/// Gets the associated .
///
- // TODO-NULLABLE: Not sure about what this is for or if it should be nullable
- IStoreFunctionParameter? StoreFunctionParameter { get; }
+ IStoreFunctionParameter StoreFunctionParameter { get; }
}
}
diff --git a/src/EFCore.Relational/Metadata/IMutableCheckConstraint.cs b/src/EFCore.Relational/Metadata/IMutableCheckConstraint.cs
index 79a750207b8..51ec32caf8d 100644
--- a/src/EFCore.Relational/Metadata/IMutableCheckConstraint.cs
+++ b/src/EFCore.Relational/Metadata/IMutableCheckConstraint.cs
@@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a check constraint in the .
///
- public interface IMutableCheckConstraint : ICheckConstraint, IMutableAnnotatable
+ public interface IMutableCheckConstraint : IReadOnlyCheckConstraint, IMutableAnnotatable
{
///
/// Gets the in which this check constraint is defined.
diff --git a/src/EFCore.Relational/Metadata/IMutableDbFunction.cs b/src/EFCore.Relational/Metadata/IMutableDbFunction.cs
index 47de4debb33..a651d451c4f 100644
--- a/src/EFCore.Relational/Metadata/IMutableDbFunction.cs
+++ b/src/EFCore.Relational/Metadata/IMutableDbFunction.cs
@@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Represents a relational database function in an in
/// the a form that can be mutated while the model is being built.
///
- public interface IMutableDbFunction : IMutableAnnotatable, IDbFunction
+ public interface IMutableDbFunction : IReadOnlyDbFunction, IMutableAnnotatable
{
///
/// Gets or sets the name of the function in the database.
diff --git a/src/EFCore.Relational/Metadata/IMutableDbFunctionParameter.cs b/src/EFCore.Relational/Metadata/IMutableDbFunctionParameter.cs
index 69327cc0018..6b2b8f760c6 100644
--- a/src/EFCore.Relational/Metadata/IMutableDbFunctionParameter.cs
+++ b/src/EFCore.Relational/Metadata/IMutableDbFunctionParameter.cs
@@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a parameter.
///
- public interface IMutableDbFunctionParameter : IMutableAnnotatable, IDbFunctionParameter
+ public interface IMutableDbFunctionParameter : IReadOnlyDbFunctionParameter, IMutableAnnotatable
{
///
/// Gets the to which this parameter belongs.
diff --git a/src/EFCore.Relational/Metadata/IMutableSequence.cs b/src/EFCore.Relational/Metadata/IMutableSequence.cs
index a979201fbd0..ada624b09c3 100644
--- a/src/EFCore.Relational/Metadata/IMutableSequence.cs
+++ b/src/EFCore.Relational/Metadata/IMutableSequence.cs
@@ -9,10 +9,9 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a database sequence in the in a form that
- /// can be mutated while building the model.
+ /// Represents a database sequence in the model.
///
- public interface IMutableSequence : ISequence, IMutableAnnotatable
+ public interface IMutableSequence : IReadOnlySequence, IMutableAnnotatable
{
///
/// Gets the in which this sequence is defined.
diff --git a/src/EFCore.Relational/Metadata/IReadOnlyCheckConstraint.cs b/src/EFCore.Relational/Metadata/IReadOnlyCheckConstraint.cs
new file mode 100644
index 00000000000..3ab910250db
--- /dev/null
+++ b/src/EFCore.Relational/Metadata/IReadOnlyCheckConstraint.cs
@@ -0,0 +1,30 @@
+// 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.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a check constraint in the .
+ ///
+ public interface IReadOnlyCheckConstraint : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the name of the check constraint in the database.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the in which this check constraint is defined.
+ ///
+ IReadOnlyEntityType EntityType { get; }
+
+ ///
+ /// Gets the constraint sql used in a check constraint in the database.
+ ///
+ string Sql { get; }
+ }
+}
diff --git a/src/EFCore.Relational/Metadata/IReadOnlyDbFunction.cs b/src/EFCore.Relational/Metadata/IReadOnlyDbFunction.cs
new file mode 100644
index 00000000000..d1447c8a85d
--- /dev/null
+++ b/src/EFCore.Relational/Metadata/IReadOnlyDbFunction.cs
@@ -0,0 +1,92 @@
+// 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.Collections.Generic;
+using System.Reflection;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
+using Microsoft.EntityFrameworkCore.Storage;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a relational database function in an .
+ ///
+ public interface IReadOnlyDbFunction : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the name of the function in the database.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the schema of the function in the database.
+ ///
+ string? Schema { get; }
+
+ ///
+ /// Gets the name of the function in the model.
+ ///
+ string ModelName { get; }
+
+ ///
+ /// Gets the model in which this function is defined.
+ ///
+ IReadOnlyModel Model { get; }
+
+ ///
+ /// Gets the CLR method which maps to the function in the database.
+ ///
+ MethodInfo? MethodInfo { get; }
+
+ ///
+ /// Gets the value indicating whether the database function is built-in.
+ ///
+ bool IsBuiltIn { get; }
+
+ ///
+ /// Gets the value indicating whether this function returns scalar value.
+ ///
+ [CA.MemberNotNullWhen(true, nameof(TypeMapping))]
+ bool IsScalar { get; }
+
+ ///
+ /// Gets the value indicating whether this function is an aggregate function.
+ ///
+ bool IsAggregate { get; }
+
+ ///
+ /// Gets the value indicating whether the database function can return null.
+ ///
+ bool IsNullable { get; }
+
+ ///
+ /// Gets the configured store type string.
+ ///
+ string? StoreType { get; }
+
+ ///
+ /// Gets the returned CLR type.
+ ///
+ Type ReturnType { get; }
+
+ ///
+ /// Gets the type mapping for the function's return type.
+ ///
+ RelationalTypeMapping? TypeMapping { get; }
+
+ ///
+ /// Gets the parameters for this function.
+ ///
+ IReadOnlyList Parameters { get; }
+
+ ///
+ /// Gets the translation callback for performing custom translation of the method call into a SQL expression fragment.
+ ///
+ Func, SqlExpression>? Translation { get; }
+ }
+}
diff --git a/src/EFCore.Relational/Metadata/IReadOnlyDbFunctionParameter.cs b/src/EFCore.Relational/Metadata/IReadOnlyDbFunctionParameter.cs
new file mode 100644
index 00000000000..7e9690240ef
--- /dev/null
+++ b/src/EFCore.Relational/Metadata/IReadOnlyDbFunctionParameter.cs
@@ -0,0 +1,48 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a parameter.
+ ///
+ public interface IReadOnlyDbFunctionParameter : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the to which this parameter belongs.
+ ///
+ IReadOnlyDbFunction Function { get; }
+
+ ///
+ /// Gets the parameter name.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the parameter type.
+ ///
+ Type ClrType { get; }
+
+ ///
+ /// Gets the store type of this parameter.
+ ///
+ string? StoreType { get; }
+
+ ///
+ /// Gets the value which indicates whether parameter propagates nullability, meaning if it's value is null the database function itself
+ /// returns null.
+ ///
+ bool PropagatesNullability { get; }
+
+ ///
+ /// Gets the for this parameter.
+ ///
+ RelationalTypeMapping? TypeMapping { get; }
+ }
+}
diff --git a/src/EFCore.Relational/Metadata/IReadOnlySequence.cs b/src/EFCore.Relational/Metadata/IReadOnlySequence.cs
new file mode 100644
index 00000000000..64bc60c9af2
--- /dev/null
+++ b/src/EFCore.Relational/Metadata/IReadOnlySequence.cs
@@ -0,0 +1,68 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a database sequence in the model.
+ ///
+ public interface IReadOnlySequence : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the name of the sequence in the database.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the database schema that contains the sequence.
+ ///
+ string? Schema { get; }
+
+ ///
+ /// Gets the in which this sequence is defined.
+ ///
+ IReadOnlyModel Model { get; }
+
+ ///
+ /// Gets the value at which the sequence will start.
+ ///
+ long StartValue { get; }
+
+ ///
+ /// Gets the amount incremented to obtain each new value in the sequence.
+ ///
+ int IncrementBy { get; }
+
+ ///
+ /// Gets the minimum value supported by the sequence, or if none has been set.
+ ///
+ long? MinValue { get; }
+
+ ///
+ /// Gets the maximum value supported by the sequence, or if none has been set.
+ ///
+ long? MaxValue { get; }
+
+ ///
+ /// Gets the of values returned by the sequence.
+ ///
+ Type Type { get; }
+
+ ///
+ /// Gets the of values returned by the sequence.
+ ///
+ [Obsolete("Use Type")]
+ Type ClrType { get; }
+
+ ///
+ /// Gets the value indicating whether the sequence will start again from the beginning when the max value
+ /// is reached.
+ ///
+ bool IsCyclic { get; }
+ }
+}
diff --git a/src/EFCore.Relational/Metadata/IRelationalAnnotationProvider.cs b/src/EFCore.Relational/Metadata/IRelationalAnnotationProvider.cs
index 820f8fa1e96..4d7056d4975 100644
--- a/src/EFCore.Relational/Metadata/IRelationalAnnotationProvider.cs
+++ b/src/EFCore.Relational/Metadata/IRelationalAnnotationProvider.cs
@@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// A service typically implemented by database providers that gives access to annotations
- /// used by relational EF Core components on various elements of the .
+ /// used by relational EF Core components on various elements of the .
///
///
/// The service lifetime is . This means a single instance
diff --git a/src/EFCore.Relational/Metadata/ISequence.cs b/src/EFCore.Relational/Metadata/ISequence.cs
index cab2584afb5..3f107cd56cc 100644
--- a/src/EFCore.Relational/Metadata/ISequence.cs
+++ b/src/EFCore.Relational/Metadata/ISequence.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
#nullable enable
@@ -9,60 +8,13 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a database sequence in the .
+ /// Represents a database sequence in the model.
///
- public interface ISequence : IAnnotatable
+ public interface ISequence : IReadOnlySequence, IAnnotatable
{
- ///
- /// Gets the name of the sequence in the database.
- ///
- string Name { get; }
-
- ///
- /// Gets the database schema that contains the sequence.
- ///
- string? Schema { get; }
-
///
/// Gets the in which this sequence is defined.
///
- IModel Model { get; }
-
- ///
- /// Gets the value at which the sequence will start.
- ///
- long StartValue { get; }
-
- ///
- /// Gets the amount incremented to obtain each new value in the sequence.
- ///
- int IncrementBy { get; }
-
- ///
- /// Gets the minimum value supported by the sequence, or if none has been set.
- ///
- long? MinValue { get; }
-
- ///
- /// Gets the maximum value supported by the sequence, or if none has been set.
- ///
- long? MaxValue { get; }
-
- ///
- /// Gets the of values returned by the sequence.
- ///
- Type Type { get; }
-
- ///
- /// Gets the of values returned by the sequence.
- ///
- [Obsolete("Use Type")]
- Type ClrType { get; }
-
- ///
- /// Gets the value indicating whether the sequence will start again from the beginning when the max value
- /// is reached.
- ///
- bool IsCyclic { get; }
+ new IModel Model { get; }
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs b/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs
index 441976dd09c..47daf600763 100644
--- a/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs
+++ b/src/EFCore.Relational/Metadata/Internal/CheckConstraint.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -19,7 +20,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 CheckConstraint : ConventionAnnotatable, IMutableCheckConstraint, IConventionCheckConstraint
+ public class CheckConstraint : ConventionAnnotatable, IMutableCheckConstraint, IConventionCheckConstraint, ICheckConstraint
{
private ConfigurationSource _configurationSource;
@@ -56,6 +57,8 @@ public CheckConstraint(
throw new InvalidOperationException(RelationalStrings.DuplicateCheckConstraint(Name, EntityType.DisplayName()));
}
+ EnsureMutable();
+
dataDictionary.Add(name, this);
}
@@ -65,7 +68,7 @@ public CheckConstraint(
/// 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 IEnumerable GetCheckConstraints([NotNull] IEntityType entityType)
+ public static IEnumerable GetCheckConstraints([NotNull] IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
@@ -79,7 +82,7 @@ public static IEnumerable GetCheckConstraints([NotNull] IEntity
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static ICheckConstraint? FindCheckConstraint(
- [NotNull] IEntityType entityType,
+ [NotNull] IReadOnlyEntityType entityType,
[NotNull] string name)
{
var dataDictionary = GetConstraintsDictionary(entityType);
@@ -106,6 +109,8 @@ public static IEnumerable GetCheckConstraints([NotNull] IEntity
if (dataDictionary != null
&& dataDictionary.TryGetValue(name, out var constraint))
{
+ constraint.EnsureMutable();
+
dataDictionary.Remove(name);
return constraint;
}
@@ -119,7 +124,12 @@ public static IEnumerable GetCheckConstraints([NotNull] IEntity
/// 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 IEntityType EntityType { get; }
+ public virtual IReadOnlyEntityType EntityType { get; }
+
+ ///
+ /// Indicates whether the check constraint is read-only.
+ ///
+ public override bool IsReadOnly => ((Annotatable)EntityType.Model).IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -157,7 +167,7 @@ public virtual void UpdateConfigurationSource(ConfigurationSource configurationS
_configurationSource = configurationSource.Max(_configurationSource);
}
- private static Dictionary? GetConstraintsDictionary(IEntityType entityType)
+ private static Dictionary? GetConstraintsDictionary(IReadOnlyEntityType entityType)
=> (Dictionary?)entityType[RelationalAnnotationNames.CheckConstraints];
///
@@ -176,7 +186,10 @@ public override string ToString()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
IConventionEntityType IConventionCheckConstraint.EntityType
- => (IConventionEntityType)EntityType;
+ {
+ [DebuggerStepThrough]
+ get => (IConventionEntityType)EntityType;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -185,6 +198,21 @@ IConventionEntityType IConventionCheckConstraint.EntityType
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
IMutableEntityType IMutableCheckConstraint.EntityType
- => (IMutableEntityType)EntityType;
+ {
+ [DebuggerStepThrough]
+ get => (IMutableEntityType)EntityType;
+ }
+
+ ///
+ /// 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 ICheckConstraint.EntityType
+ {
+ [DebuggerStepThrough]
+ get => (IEntityType)EntityType;
+ }
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/ColumnBase.cs b/src/EFCore.Relational/Metadata/Internal/ColumnBase.cs
index 2d259fa85f8..734afda10b8 100644
--- a/src/EFCore.Relational/Metadata/Internal/ColumnBase.cs
+++ b/src/EFCore.Relational/Metadata/Internal/ColumnBase.cs
@@ -32,16 +32,44 @@ public ColumnBase([NotNull] string name, [NotNull] string type, [NotNull] TableB
Table = table;
}
- ///
+ ///
+ /// 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 string Name { get; }
- ///
- public virtual ITableBase Table { get; }
+ ///
+ /// 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 TableBase Table { get; }
- ///
+ ///
+ /// 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 override bool IsReadOnly => Table.Model.IsReadOnly;
+
+ ///
+ /// 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 string StoreType { get; }
- ///
+ ///
+ /// 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 IsNullable { get; set; }
///
@@ -72,5 +100,12 @@ IEnumerable IColumnBase.PropertyMappings
[DebuggerStepThrough]
get => PropertyMappings;
}
+
+ ///
+ ITableBase IColumnBase.Table
+ {
+ [DebuggerStepThrough]
+ get => Table;
+ }
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/ColumnMapping.cs b/src/EFCore.Relational/Metadata/Internal/ColumnMapping.cs
index 6a5553d9cdc..2139c909a3b 100644
--- a/src/EFCore.Relational/Metadata/Internal/ColumnMapping.cs
+++ b/src/EFCore.Relational/Metadata/Internal/ColumnMapping.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 System.Diagnostics;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
@@ -27,9 +28,8 @@ public class ColumnMapping : ColumnMappingBase, IColumnMapping
public ColumnMapping(
[NotNull] IProperty property,
[NotNull] Column column,
- [NotNull] RelationalTypeMapping typeMapping,
[NotNull] TableMapping tableMapping)
- : base(property, column, typeMapping, tableMapping)
+ : base(property, column, tableMapping)
{
}
@@ -37,6 +37,10 @@ public ColumnMapping(
public new virtual ITableMapping TableMapping
=> (ITableMapping)base.TableMapping;
+ ///
+ public override RelationalTypeMapping TypeMapping => Property.FindRelationalTypeMapping(
+ StoreObjectIdentifier.Table(TableMapping.Table.Name, TableMapping.Table.Schema))!;
+
///
/// 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
diff --git a/src/EFCore.Relational/Metadata/Internal/ColumnMappingBase.cs b/src/EFCore.Relational/Metadata/Internal/ColumnMappingBase.cs
index 28ef0d57a68..3440c8c5464 100644
--- a/src/EFCore.Relational/Metadata/Internal/ColumnMappingBase.cs
+++ b/src/EFCore.Relational/Metadata/Internal/ColumnMappingBase.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.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
@@ -26,25 +27,55 @@ public class ColumnMappingBase : Annotatable, IColumnMappingBase
public ColumnMappingBase(
[NotNull] IProperty property,
[NotNull] ColumnBase column,
- [NotNull] RelationalTypeMapping typeMapping,
[NotNull] TableMappingBase tableMapping)
{
Property = property;
Column = column;
- TypeMapping = typeMapping;
TableMapping = tableMapping;
}
///
public virtual IProperty Property { get; }
+ ///
+ /// 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 ColumnBase Column { get; }
+
///
- public virtual IColumnBase Column { get; }
+ public virtual RelationalTypeMapping TypeMapping => Property.GetRelationalTypeMapping();
+
+ ///
+ /// 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 TableMappingBase TableMapping { get; }
+
+ ///
+ /// 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 override bool IsReadOnly => TableMapping.IsReadOnly;
///
- public virtual RelationalTypeMapping TypeMapping { get; }
+ IColumnBase IColumnMappingBase.Column
+ {
+ [DebuggerStepThrough]
+ get => Column;
+ }
///
- public virtual ITableMappingBase TableMapping { get; }
+ ITableMappingBase IColumnMappingBase.TableMapping
+ {
+ [DebuggerStepThrough]
+ get => TableMapping;
+ }
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs
index 2f8b79fe263..0c4c19d395a 100644
--- a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs
+++ b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs
@@ -16,7 +16,6 @@
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -28,7 +27,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 DbFunction : ConventionAnnotatable, IMutableDbFunction, IConventionDbFunction
+ public class DbFunction : ConventionAnnotatable, IMutableDbFunction, IConventionDbFunction, IDbFunction
{
private readonly List _parameters;
private string? _schema;
@@ -180,13 +179,18 @@ public virtual bool IsInModel
public virtual void SetRemovedFromModel()
=> _builder = null;
+ ///
+ /// Indicates whether the function is read-only.
+ ///
+ public override bool IsReadOnly => ((Annotatable)Model).IsReadOnly;
+
///
/// 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 IEnumerable GetDbFunctions([NotNull] IModel model)
+ public static IEnumerable GetDbFunctions([NotNull] IReadOnlyModel model)
=> ((SortedDictionary?)model[RelationalAnnotationNames.DbFunctions])
?.Values
?? Enumerable.Empty();
@@ -197,7 +201,7 @@ public static IEnumerable GetDbFunctions([NotNull] IModel model)
/// 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 DbFunction? FindDbFunction([NotNull] IModel model, [NotNull] MethodInfo methodInfo)
+ public static DbFunction? FindDbFunction([NotNull] IReadOnlyModel model, [NotNull] MethodInfo methodInfo)
=> model[RelationalAnnotationNames.DbFunctions] is SortedDictionary functions
&& functions.TryGetValue(GetFunctionName(methodInfo, methodInfo.GetParameters()), out var dbFunction)
? dbFunction
@@ -209,7 +213,7 @@ public static IEnumerable GetDbFunctions([NotNull] IModel model)
/// 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 DbFunction? FindDbFunction([NotNull] IModel model, [NotNull] string name)
+ public static DbFunction? FindDbFunction([NotNull] IReadOnlyModel model, [NotNull] string name)
=> model[RelationalAnnotationNames.DbFunctions] is SortedDictionary functions
&& functions.TryGetValue(name, out var dbFunction)
? dbFunction
@@ -349,6 +353,8 @@ public virtual string? Schema
///
public virtual string? SetSchema([CanBeNull] string? schema, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_schema = schema;
_schemaConfigurationSource = schema == null
@@ -389,6 +395,8 @@ public virtual string Name
{
Check.NullButNotEmpty(name, nameof(name));
+ EnsureMutable();
+
_name = name;
_nameConfigurationSource = name == null
@@ -427,6 +435,8 @@ public virtual bool IsBuiltIn
///
public virtual bool SetIsBuiltIn(bool builtIn, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_builtIn = builtIn;
_builtInConfigurationSource = configurationSource.Max(_builtInConfigurationSource);
@@ -462,6 +472,8 @@ public virtual bool IsNullable
///
public virtual bool SetIsNullable(bool nullable, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
if (!IsScalar)
{
throw new InvalidOperationException(RelationalStrings.NonScalarFunctionCannotBeNullable(Name));
@@ -502,6 +514,8 @@ public virtual string? StoreType
///
public virtual string? SetStoreType([CanBeNull] string? storeType, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_storeType = storeType;
_storeTypeConfigurationSource = storeType == null
@@ -582,6 +596,8 @@ public virtual Func, SqlExpression>? Translation
[CanBeNull] Func, SqlExpression>? translation,
ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
if (translation != null
&& (!IsScalar || IsAggregate))
{
@@ -606,6 +622,18 @@ public virtual Func, SqlExpression>? Translation
public virtual ConfigurationSource? GetTranslationConfigurationSource()
=> _translationConfigurationSource;
+ ///
+ /// 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 IReadOnlyList Parameters
+ {
+ [DebuggerStepThrough]
+ get => _parameters;
+ }
+
///
/// 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
@@ -631,7 +659,7 @@ IConventionDbFunctionBuilder IConventionDbFunction.Builder
}
///
- IModel IDbFunction.Model
+ IReadOnlyModel IReadOnlyDbFunction.Model
{
[DebuggerStepThrough]
get => Model;
@@ -644,20 +672,15 @@ IConventionModel IConventionDbFunction.Model
get => (IConventionModel)Model;
}
- ///
- /// 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 IReadOnlyList Parameters
+ ///
+ IModel IDbFunction.Model
{
[DebuggerStepThrough]
- get => _parameters;
+ get => (IModel)Model;
}
///
- IReadOnlyList IDbFunction.Parameters
+ IReadOnlyList IReadOnlyDbFunction.Parameters
{
[DebuggerStepThrough]
get => _parameters;
@@ -677,6 +700,13 @@ IReadOnlyList IMutableDbFunction.Parameters
get => _parameters;
}
+ ///
+ IReadOnlyList IDbFunction.Parameters
+ {
+ [DebuggerStepThrough]
+ get => _parameters;
+ }
+
///
/// 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
diff --git a/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs b/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs
index a70b1a4a67e..1494e9a44b2 100644
--- a/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs
+++ b/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs
@@ -10,7 +10,6 @@
using Microsoft.EntityFrameworkCore.Metadata.Builders.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -22,7 +21,11 @@ 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 DbFunctionParameter : ConventionAnnotatable, IMutableDbFunctionParameter, IConventionDbFunctionParameter
+ public class DbFunctionParameter :
+ ConventionAnnotatable,
+ IMutableDbFunctionParameter,
+ IConventionDbFunctionParameter,
+ IDbFunctionParameter
{
private string? _storeType;
private RelationalTypeMapping? _typeMapping;
@@ -81,7 +84,7 @@ IConventionDbFunction IConventionDbFunctionParameter.Function
}
///
- IDbFunction IDbFunctionParameter.Function
+ IReadOnlyDbFunction IReadOnlyDbFunctionParameter.Function
{
[DebuggerStepThrough]
get => Function;
@@ -240,13 +243,23 @@ public virtual bool SetPropagatesNullability(bool propagatesNullability, Configu
public override string ToString()
=> this.ToDebugString(MetadataDebugStringOptions.SingleLineDefault);
+ ///
+ string IDbFunctionParameter.StoreType
+ {
+ [DebuggerStepThrough]
+ get => StoreType!; // Model validation ensures all parameters have a type mapping
+ }
+
+ ///
+ IDbFunction IDbFunctionParameter.Function
+ {
+ [DebuggerStepThrough]
+ get => Function;
+ }
+
///
[DebuggerStepThrough]
RelationalTypeMapping? IConventionDbFunctionParameter.SetTypeMapping(RelationalTypeMapping? typeMapping, bool fromDataAnnotation)
=> SetTypeMapping(typeMapping, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
-
- ///
- string IDbFunctionParameter.StoreType
- => StoreType!; // Model validation ensures all parameters have a type mapping
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/FunctionColumnMapping.cs b/src/EFCore.Relational/Metadata/Internal/FunctionColumnMapping.cs
index 8dcafbee728..d4a1b14c807 100644
--- a/src/EFCore.Relational/Metadata/Internal/FunctionColumnMapping.cs
+++ b/src/EFCore.Relational/Metadata/Internal/FunctionColumnMapping.cs
@@ -27,9 +27,8 @@ public class FunctionColumnMapping : ColumnMappingBase, IFunctionColumnMapping
public FunctionColumnMapping(
[NotNull] IProperty property,
[NotNull] FunctionColumn column,
- [NotNull] RelationalTypeMapping typeMapping,
[NotNull] FunctionMapping viewMapping)
- : base(property, column, typeMapping, viewMapping)
+ : base(property, column, viewMapping)
{
}
@@ -37,6 +36,10 @@ public FunctionColumnMapping(
public virtual IFunctionMapping FunctionMapping
=> (IFunctionMapping)TableMapping;
+ ///
+ public override RelationalTypeMapping TypeMapping => Property.FindRelationalTypeMapping(
+ StoreObjectIdentifier.DbFunction(FunctionMapping.DbFunction.Name))!;
+
///
/// 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
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalEntityTypeExtensions.cs
index e1c8604271c..f3e59ab0534 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalEntityTypeExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalEntityTypeExtensions.cs
@@ -32,7 +32,8 @@ public static class RelationalEntityTypeExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static IEnumerable GetViewOrTableMappings([NotNull] this IEntityType entityType)
- => (IEnumerable?)(entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.ViewMappings)
+ => (IEnumerable?)(entityType.FindRuntimeAnnotationValue(
+ RelationalAnnotationNames.ViewMappings)
?? entityType.FindRuntimeAnnotationValue(RelationalAnnotationNames.TableMappings))
?? Enumerable.Empty();
@@ -42,7 +43,7 @@ public static IEnumerable GetViewOrTableMappings([NotNull] th
/// 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 IReadOnlyList GetTptDiscriminatorValues([NotNull] this IEntityType entityType)
+ public static IReadOnlyList GetTptDiscriminatorValues([NotNull] this IReadOnlyEntityType entityType)
=> entityType.GetConcreteDerivedTypesInclusive().Select(et => et.ShortName()).ToList();
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs
index e784f74e10f..4f0b65d0de7 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs
@@ -27,8 +27,8 @@ public static class RelationalForeignKeyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatible(
- [NotNull] this IForeignKey foreignKey,
- [NotNull] IForeignKey duplicateForeignKey,
+ [NotNull] this IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyForeignKey duplicateForeignKey,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
index df8f09a8b22..072bfc74197 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
@@ -26,8 +26,8 @@ public static class RelationalIndexExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatible(
- [NotNull] this IIndex index,
- [NotNull] IIndex duplicateIndex,
+ [NotNull] this IReadOnlyIndex index,
+ [NotNull] IReadOnlyIndex duplicateIndex,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
index 3c0d2d11771..ffc27a7035d 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
@@ -26,8 +26,8 @@ public static class RelationalKeyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatible(
- [NotNull] this IKey key,
- [NotNull] IKey duplicateKey,
+ [NotNull] this IReadOnlyKey key,
+ [NotNull] IReadOnlyKey duplicateKey,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs b/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs
index b271241a2f6..968962105ee 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalModel.cs
@@ -258,8 +258,7 @@ private static void AddDefaultMappings(RelationalModel databaseModel, IEntityTyp
column.IsNullable = false;
}
- var columnMapping = new ColumnMappingBase(
- property, column, property.FindRelationalTypeMapping()!, tableMapping);
+ var columnMapping = new ColumnMappingBase(property, column, tableMapping);
tableMapping.ColumnMappings.Add(columnMapping);
column.PropertyMappings.Add(columnMapping);
@@ -352,8 +351,7 @@ private static void AddTables(RelationalModel databaseModel, IEntityType entityT
column.IsNullable = false;
}
- var columnMapping = new ColumnMapping(
- property, column, property.FindRelationalTypeMapping(mappedTable)!, tableMapping);
+ var columnMapping = new ColumnMapping(property, column, tableMapping);
tableMapping.ColumnMappings.Add(columnMapping);
column.PropertyMappings.Add(columnMapping);
@@ -444,8 +442,7 @@ private static void AddViews(RelationalModel databaseModel, IEntityType entityTy
column.IsNullable = false;
}
- var columnMapping = new ViewColumnMapping(
- property, column, property.FindRelationalTypeMapping(mappedView)!, viewMapping);
+ var columnMapping = new ViewColumnMapping(property, column, viewMapping);
viewMapping.ColumnMappings.Add(columnMapping);
column.PropertyMappings.Add(columnMapping);
@@ -550,8 +547,7 @@ private static void AddSqlQueries(RelationalModel databaseModel, IEntityType ent
column.IsNullable = false;
}
- var columnMapping = new SqlQueryColumnMapping(
- property, column, property.FindRelationalTypeMapping(mappedQuery)!, queryMapping);
+ var columnMapping = new SqlQueryColumnMapping(property, column, queryMapping);
queryMapping.ColumnMappings.Add(columnMapping);
column.PropertyMappings.Add(columnMapping);
@@ -631,7 +627,7 @@ private static void AddMappedFunctions(RelationalModel databaseModel, IEntityTyp
private static void AddTVFs(RelationalModel relationalModel)
{
- var model = (IConventionModel)relationalModel.Model;
+ var model = relationalModel.Model;
foreach (DbFunction function in model.GetDbFunctions())
{
var entityType = function.IsScalar
@@ -700,8 +696,7 @@ private static FunctionMapping CreateFunctionMapping(
column.IsNullable = false;
}
- var columnMapping = new FunctionColumnMapping(
- property, column, property.FindRelationalTypeMapping(mappedFunction)!, functionMapping);
+ var columnMapping = new FunctionColumnMapping(property, column, functionMapping);
functionMapping.ColumnMappings.Add(columnMapping);
column.PropertyMappings.Add(columnMapping);
@@ -756,7 +751,7 @@ private static void PopulateConstraints(Table table)
continue;
}
- var entityType = (IConventionEntityType)entityTypeMapping.EntityType;
+ var entityType = (IEntityType)entityTypeMapping.EntityType;
foreach (var foreignKey in entityType.GetForeignKeys())
{
var firstPrincipalMapping = true;
@@ -843,7 +838,7 @@ private static void PopulateConstraints(Table table)
if (entityTypeMapping.IncludesDerivedTypes
&& foreignKey.DeclaringEntityType != entityType
- && entityType.FindPrimaryKey() is IConventionKey primaryKey
+ && entityType.FindPrimaryKey() is IKey primaryKey
&& foreignKey.Properties.SequenceEqual(primaryKey.Properties))
{
// The identifying FK constraint is needed to be created only on the table that corresponds
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs
index 460b73fac53..23fec198a62 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyExtensions.cs
@@ -23,7 +23,7 @@ public static class RelationalPropertyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- public static string? GetConfiguredColumnType([NotNull] this IProperty property)
+ public static string? GetConfiguredColumnType([NotNull] this IReadOnlyProperty property)
=> (string?)property[RelationalAnnotationNames.ColumnType];
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
index 50610150fb8..547a7ec5f58 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
@@ -63,7 +63,7 @@ public virtual string? ColumnName
/// 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 RelationalPropertyOverrides? Find([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
+ public static RelationalPropertyOverrides? Find([NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var tableOverrides = (SortedDictionary?)
property[RelationalAnnotationNames.RelationalOverrides];
diff --git a/src/EFCore.Relational/Metadata/Internal/Sequence.cs b/src/EFCore.Relational/Metadata/Internal/Sequence.cs
index a5798286166..71db8af6fa3 100644
--- a/src/EFCore.Relational/Metadata/Internal/Sequence.cs
+++ b/src/EFCore.Relational/Metadata/Internal/Sequence.cs
@@ -24,7 +24,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 Sequence : ConventionAnnotatable, IMutableSequence, IConventionSequence
+ public class Sequence : ConventionAnnotatable, IMutableSequence, IConventionSequence, ISequence
{
private readonly string? _schema;
private long? _startValue;
@@ -100,7 +100,7 @@ public class Sequence : ConventionAnnotatable, IMutableSequence, IConventionSequ
public Sequence(
[NotNull] string name,
[CanBeNull] string? schema,
- [NotNull] IModel model,
+ [NotNull] IReadOnlyModel model,
ConfigurationSource configurationSource)
{
Check.NotEmpty(name, nameof(name));
@@ -120,7 +120,7 @@ public Sequence(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[Obsolete("Use the other constructor")]
- public Sequence([NotNull] IModel model, [NotNull] string annotationName)
+ public Sequence([NotNull] IReadOnlyModel model, [NotNull] string annotationName)
{
Check.NotNull(model, nameof(model));
Check.NotEmpty(annotationName, nameof(annotationName));
@@ -146,7 +146,7 @@ public Sequence([NotNull] IModel model, [NotNull] string annotationName)
/// 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 IEnumerable GetSequences([NotNull] IModel model)
+ public static IEnumerable GetSequences([NotNull] IReadOnlyModel model)
=> ((SortedDictionary<(string, string?), Sequence>?)model[RelationalAnnotationNames.Sequences])
?.Values
?? Enumerable.Empty();
@@ -157,7 +157,7 @@ public static IEnumerable GetSequences([NotNull] IModel model)
/// 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 Sequence? FindSequence([NotNull] IModel model, [NotNull] string name, [CanBeNull] string? schema)
+ public static Sequence? FindSequence([NotNull] IReadOnlyModel model, [NotNull] string name, [CanBeNull] string? schema)
{
var sequences = (SortedDictionary<(string, string?), Sequence>?)model[RelationalAnnotationNames.Sequences];
if (sequences == null
@@ -208,6 +208,8 @@ public static Sequence AddSequence(
Check.NotNull(sequence, nameof(sequence));
Check.NotEmpty(name, nameof(name));
+ sequence.EnsureMutable();
+
var sequences = (SortedDictionary<(string, string?), Sequence>?)model[RelationalAnnotationNames.Sequences];
var tuple = (sequence.Name, sequence.Schema);
if (sequences == null
@@ -281,7 +283,12 @@ public virtual void SetRemovedFromModel()
/// 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 IModel Model { get; }
+ public virtual IReadOnlyModel Model { get; }
+
+ ///
+ /// Indicates whether the sequence is read-only.
+ ///
+ public override bool IsReadOnly => ((Annotatable)Model).IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -338,6 +345,8 @@ public virtual long StartValue
///
public virtual long? SetStartValue(long? startValue, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_startValue = startValue;
_startValueConfigurationSource = startValue == null
@@ -376,6 +385,8 @@ public virtual int IncrementBy
///
public virtual int? SetIncrementBy(int? incrementBy, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_incrementBy = incrementBy;
_incrementByConfigurationSource = incrementBy == null
@@ -414,6 +425,8 @@ public virtual long? MinValue
///
public virtual long? SetMinValue(long? minValue, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_minValue = minValue;
_minValueConfigurationSource = minValue == null
@@ -452,6 +465,8 @@ public virtual long? MaxValue
///
public virtual long? SetMaxValue(long? maxValue, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_maxValue = maxValue;
_maxValueConfigurationSource = maxValue == null
@@ -499,6 +514,8 @@ public virtual Type Type
///
public virtual Type? SetType([CanBeNull] Type? type, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
if (type != null
&& !SupportedTypes.Contains(type))
{
@@ -576,6 +593,8 @@ public virtual bool IsCyclic
///
public virtual bool? SetIsCyclic(bool? cyclic, ConfigurationSource configurationSource)
{
+ EnsureMutable();
+
_isCyclic = cyclic;
_isCyclicConfigurationSource = cyclic == null
@@ -610,7 +629,10 @@ public override string ToString()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
IConventionSequenceBuilder IConventionSequence.Builder
- => Builder;
+ {
+ [DebuggerStepThrough]
+ get => Builder;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -619,7 +641,10 @@ IConventionSequenceBuilder IConventionSequence.Builder
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
IMutableModel IMutableSequence.Model
- => (IMutableModel)Model;
+ {
+ [DebuggerStepThrough]
+ get => (IMutableModel)Model;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -628,7 +653,22 @@ IMutableModel IMutableSequence.Model
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
IConventionModel IConventionSequence.Model
- => (IConventionModel)Model;
+ {
+ [DebuggerStepThrough]
+ get => (IConventionModel)Model;
+ }
+
+ ///
+ /// 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.
+ ///
+ IModel ISequence.Model
+ {
+ [DebuggerStepThrough]
+ get => (IModel)Model;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -636,6 +676,7 @@ IConventionModel IConventionSequence.Model
/// 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]
long? IConventionSequence.SetStartValue(long? startValue, bool fromDataAnnotation)
=> SetStartValue(startValue, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -645,6 +686,7 @@ IConventionModel IConventionSequence.Model
/// 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]
int? IConventionSequence.SetIncrementBy(int? incrementBy, bool fromDataAnnotation)
=> SetIncrementBy(incrementBy, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -654,6 +696,7 @@ IConventionModel IConventionSequence.Model
/// 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]
long? IConventionSequence.SetMinValue(long? minValue, bool fromDataAnnotation)
=> SetMinValue(minValue, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -663,6 +706,7 @@ IConventionModel IConventionSequence.Model
/// 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]
long? IConventionSequence.SetMaxValue(long? maxValue, bool fromDataAnnotation)
=> SetMaxValue(maxValue, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -672,6 +716,7 @@ IConventionModel IConventionSequence.Model
/// 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]
Type? IConventionSequence.SetClrType(Type? type, bool fromDataAnnotation)
=> SetType(type, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -681,6 +726,7 @@ IConventionModel IConventionSequence.Model
/// 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]
Type? IConventionSequence.SetType(Type? type, bool fromDataAnnotation)
=> SetType(type, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -690,6 +736,7 @@ IConventionModel IConventionSequence.Model
/// 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]
bool? IConventionSequence.SetIsCyclic(bool? cyclic, bool fromDataAnnotation)
=> SetIsCyclic(cyclic, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
diff --git a/src/EFCore.Relational/Metadata/Internal/SqlQueryColumnMapping.cs b/src/EFCore.Relational/Metadata/Internal/SqlQueryColumnMapping.cs
index bb9fc36c282..b75f39e09d1 100644
--- a/src/EFCore.Relational/Metadata/Internal/SqlQueryColumnMapping.cs
+++ b/src/EFCore.Relational/Metadata/Internal/SqlQueryColumnMapping.cs
@@ -27,9 +27,8 @@ public class SqlQueryColumnMapping : ColumnMappingBase, ISqlQueryColumnMapping
public SqlQueryColumnMapping(
[NotNull] IProperty property,
[NotNull] SqlQueryColumn column,
- [NotNull] RelationalTypeMapping typeMapping,
[NotNull] SqlQueryMapping sqlQueryMapping)
- : base(property, column, typeMapping, sqlQueryMapping)
+ : base(property, column, sqlQueryMapping)
{
}
@@ -37,6 +36,10 @@ public SqlQueryColumnMapping(
public virtual ISqlQueryMapping SqlQueryMapping
=> (ISqlQueryMapping)TableMapping;
+ ///
+ public override RelationalTypeMapping TypeMapping => Property.FindRelationalTypeMapping(
+ StoreObjectIdentifier.SqlQuery(SqlQueryMapping.SqlQuery.Name))!;
+
///
/// 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
diff --git a/src/EFCore.Relational/Metadata/Internal/TableBase.cs b/src/EFCore.Relational/Metadata/Internal/TableBase.cs
index 67aa1f3d86b..637c38158a7 100644
--- a/src/EFCore.Relational/Metadata/Internal/TableBase.cs
+++ b/src/EFCore.Relational/Metadata/Internal/TableBase.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -47,7 +48,20 @@ public TableBase([NotNull] string name, [CanBeNull] string? schema, [NotNull] Re
///
public virtual RelationalModel Model { get; }
- ///
+ ///
+ /// 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 override bool IsReadOnly => Model.IsReadOnly;
+
+ ///
+ /// 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 IsShared { get; set; }
///
@@ -132,15 +146,24 @@ private void CheckMappedEntityType(IEntityType entityType)
///
IRelationalModel ITableBase.Model
- => Model;
+ {
+ [DebuggerStepThrough]
+ get => Model;
+ }
///
IEnumerable ITableBase.EntityTypeMappings
- => EntityTypeMappings;
+ {
+ [DebuggerStepThrough]
+ get => EntityTypeMappings;
+ }
///
IEnumerable ITableBase.Columns
- => Columns.Values;
+ {
+ [DebuggerStepThrough]
+ get => Columns.Values;
+ }
///
IEnumerable ITableBase.GetRowInternalForeignKeys(IEntityType entityType)
diff --git a/src/EFCore.Relational/Metadata/Internal/TableMappingBase.cs b/src/EFCore.Relational/Metadata/Internal/TableMappingBase.cs
index 96f21ad2422..6e11f15df3b 100644
--- a/src/EFCore.Relational/Metadata/Internal/TableMappingBase.cs
+++ b/src/EFCore.Relational/Metadata/Internal/TableMappingBase.cs
@@ -26,7 +26,7 @@ public class TableMappingBase : Annotatable, ITableMappingBase
///
public TableMappingBase(
[NotNull] IEntityType entityType,
- [NotNull] ITableBase table,
+ [NotNull] TableBase table,
bool includesDerivedTypes)
{
EntityType = entityType;
@@ -37,8 +37,21 @@ public TableMappingBase(
///
public virtual IEntityType EntityType { get; }
- ///
- public virtual ITableBase Table { get; }
+ ///
+ /// 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 TableBase Table { get; }
+
+ ///
+ /// 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 override bool IsReadOnly => Table.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -46,7 +59,7 @@ public TableMappingBase(
/// 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 SortedSet ColumnMappings { get; }
+ public virtual SortedSet ColumnMappings { get; }
= new(ColumnMappingBaseComparer.Instance);
///
@@ -63,5 +76,11 @@ IEnumerable ITableMappingBase.ColumnMappings
[DebuggerStepThrough]
get => ColumnMappings;
}
+
+ ITableBase ITableMappingBase.Table
+ {
+ [DebuggerStepThrough]
+ get => Table;
+ }
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/ViewColumnMapping.cs b/src/EFCore.Relational/Metadata/Internal/ViewColumnMapping.cs
index ea7e34a8f64..c3d35a0391d 100644
--- a/src/EFCore.Relational/Metadata/Internal/ViewColumnMapping.cs
+++ b/src/EFCore.Relational/Metadata/Internal/ViewColumnMapping.cs
@@ -27,9 +27,8 @@ public class ViewColumnMapping : ColumnMappingBase, IViewColumnMapping
public ViewColumnMapping(
[NotNull] IProperty property,
[NotNull] ViewColumn column,
- [NotNull] RelationalTypeMapping typeMapping,
[NotNull] ViewMapping viewMapping)
- : base(property, column, typeMapping, viewMapping)
+ : base(property, column, viewMapping)
{
}
@@ -37,6 +36,10 @@ public ViewColumnMapping(
public virtual IViewMapping ViewMapping
=> (IViewMapping)TableMapping;
+ ///
+ public override RelationalTypeMapping TypeMapping => Property.FindRelationalTypeMapping(
+ StoreObjectIdentifier.View(ViewMapping.View.Name, ViewMapping.View.Schema))!;
+
///
/// 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
diff --git a/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs b/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs
index 7e3d3150c6b..14a481cab6c 100644
--- a/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs
+++ b/src/EFCore.Relational/Metadata/RelationalAnnotationProvider.cs
@@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// A base class inherited by database providers that gives access to annotations
- /// used by relational EF Core components on various elements of the .
+ /// used by relational EF Core components on various elements of the .
///
///
/// The service lifetime is . This means a single instance
diff --git a/src/EFCore.Relational/Metadata/SequenceExtensions.cs b/src/EFCore.Relational/Metadata/SequenceExtensions.cs
index 020b215fc90..e940a015192 100644
--- a/src/EFCore.Relational/Metadata/SequenceExtensions.cs
+++ b/src/EFCore.Relational/Metadata/SequenceExtensions.cs
@@ -10,7 +10,7 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Extension methods for .
+ /// Sequence extension methods.
///
public static class SequenceExtensions
{
@@ -28,7 +28,7 @@ public static class SequenceExtensions
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this ISequence sequence,
+ [NotNull] this IReadOnlySequence sequence,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs b/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
index dafaec08afa..a286e489f90 100644
--- a/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
+++ b/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
@@ -27,7 +27,7 @@ private StoreObjectIdentifier(StoreObjectType storeObjectType, string name, stri
/// The entity type.
/// The store object type.
/// The store object id.
- public static StoreObjectIdentifier? Create([NotNull] IEntityType entityType, StoreObjectType type)
+ public static StoreObjectIdentifier? Create([NotNull] IReadOnlyEntityType entityType, StoreObjectType type)
{
Check.NotNull(entityType, nameof(entityType));
@@ -81,7 +81,7 @@ public static StoreObjectIdentifier View([NotNull] string name, [CanBeNull] stri
///
/// The entity type.
/// The SQL query id.
- public static StoreObjectIdentifier SqlQuery([NotNull] IEntityType entityType)
+ public static StoreObjectIdentifier SqlQuery([NotNull] IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs
index 7ab5b2d278b..e5a6759fc8e 100644
--- a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs
+++ b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs
@@ -600,7 +600,7 @@ protected virtual IEnumerable Diff(
// Populate column mapping
foreach(var _ in Diff(source.Columns, target.Columns, diffContext))
{ }
-
+
yield break;
}
@@ -951,26 +951,14 @@ private static bool EntityTypePathEquals(IEntityType source, IEntityType target,
return false;
}
- var nextSource = GetLinkedPrincipal(source);
- var nextTarget = GetLinkedPrincipal(target);
+ var nextSource = sourceTable.GetRowInternalForeignKeys(source).FirstOrDefault()?.PrincipalEntityType;
+ var nextTarget = targetTable.GetRowInternalForeignKeys(target).FirstOrDefault()?.PrincipalEntityType;
return (nextSource == null && nextTarget == null)
|| (nextSource != null
&& nextTarget != null
&& EntityTypePathEquals(nextSource, nextTarget, diffContext));
}
- private static IEntityType GetLinkedPrincipal(IEntityType entityType)
- {
- var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
- if (table == null)
- {
- return null;
- }
-
- var linkingForeignKey = entityType.FindRowInternalForeignKeys(table.Value).FirstOrDefault();
- return linkingForeignKey?.PrincipalEntityType;
- }
-
///
/// 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
diff --git a/src/EFCore.Relational/Migrations/Migration.cs b/src/EFCore.Relational/Migrations/Migration.cs
index fd38f5dc7c3..24dfd72a767 100644
--- a/src/EFCore.Relational/Migrations/Migration.cs
+++ b/src/EFCore.Relational/Migrations/Migration.cs
@@ -36,7 +36,7 @@ IModel Create()
var modelBuilder = new ModelBuilder();
BuildTargetModel(modelBuilder);
- return modelBuilder.Model;
+ return (IModel)modelBuilder.Model;
}
return _targetModel ??= Create();
diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
index b573062cbbd..1086841a62e 100644
--- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
@@ -1513,7 +1513,7 @@ private static Expression AddConvertToObject(Expression expression)
var propertyExpressions = new Dictionary();
foreach (var property in entityType
.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredProperties))
+ .SelectMany(t => t.GetDeclaredProperties()))
{
propertyExpressions[property] = new ColumnExpression(
property, table.FindColumn(property)!, tableExpression, nullable || !property.IsPrimaryKey());
@@ -1556,7 +1556,8 @@ private static IDictionary GetPropertyExpressionsFr
{
var propertyExpressions = new Dictionary();
foreach (var property in entityType
- .GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive()).SelectMany(EntityTypeExtensions.GetDeclaredProperties))
+ .GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
+ .SelectMany(t => t.GetDeclaredProperties()))
{
propertyExpressions[property] = new ColumnExpression(
property, table.FindColumn(property)!, tableExpression, nullable: true);
diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
index b7e5fae29ca..1b00f5989a8 100644
--- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
+++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
@@ -388,7 +388,7 @@ public void ClearProjection()
private static IEnumerable GetAllPropertiesInHierarchy(IEntityType entityType)
=> entityType.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredProperties);
+ .SelectMany(t => t.GetDeclaredProperties());
///
/// Replaces current projection mapping with a new one to change what is being projected out from this .
@@ -1210,7 +1210,7 @@ EntityProjectionExpression LiftEntityProjectionFromSubquery(EntityProjectionExpr
// Also lift nested entity projections
foreach (var navigation in entityProjection.EntityType
.GetAllBaseTypes().Concat(entityProjection.EntityType.GetDerivedTypesInclusive())
- .SelectMany(EntityTypeExtensions.GetDeclaredNavigations))
+ .SelectMany(t => t.GetDeclaredNavigations()))
{
var boundEntityShaperExpression = entityProjection.BindNavigation(navigation);
if (boundEntityShaperExpression != null)
diff --git a/src/EFCore.SqlServer/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs b/src/EFCore.SqlServer/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs
index bdfab7b547e..c880839b1cd 100644
--- a/src/EFCore.SqlServer/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs
+++ b/src/EFCore.SqlServer/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs
@@ -27,7 +27,7 @@ public ConflictingValueGenerationStrategiesEventData(
[NotNull] Func messageGenerator,
SqlServerValueGenerationStrategy sqlServerValueGenerationStrategy,
[NotNull] string otherValueGenerationStrategy,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
: base(eventDefinition, messageGenerator)
{
SqlServerValueGenerationStrategy = sqlServerValueGenerationStrategy;
@@ -48,6 +48,6 @@ public ConflictingValueGenerationStrategiesEventData(
///
/// The property.
///
- public virtual IProperty Property { get; }
+ public virtual IReadOnlyProperty Property { get; }
}
}
diff --git a/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs b/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs
index cdaece713e9..c5f61d84d51 100644
--- a/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/Internal/SqlServerLoggerExtensions.cs
@@ -138,7 +138,7 @@ public static void ConflictingValueGenerationStrategiesWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
SqlServerValueGenerationStrategy sqlServerValueGenerationStrategy,
[NotNull] string otherValueGenerationStrategy,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
{
var definition = SqlServerResources.LogConflictingValueGenerationStrategies(diagnostics);
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs
index a844912caad..63db54e4b6b 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs
@@ -11,7 +11,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for SQL Server-specific metadata.
+ /// Entity type extension methods for SQL Server-specific metadata.
///
public static class SqlServerEntityTypeExtensions
{
@@ -20,7 +20,7 @@ public static class SqlServerEntityTypeExtensions
///
/// The entity type.
/// if the entity type is mapped to a memory-optimized table.
- public static bool IsMemoryOptimized([NotNull] this IEntityType entityType)
+ public static bool IsMemoryOptimized([NotNull] this IReadOnlyEntityType entityType)
=> entityType[SqlServerAnnotationNames.MemoryOptimized] as bool? ?? false;
///
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
index fbc8271b725..a3dc6ae61f6 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
@@ -13,7 +13,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for SQL Server-specific metadata.
+ /// Index extension methods for SQL Server-specific metadata.
///
public static class SqlServerIndexExtensions
{
@@ -22,7 +22,7 @@ public static class SqlServerIndexExtensions
///
/// The index.
/// if the index is clustered.
- public static bool? IsClustered([NotNull] this IIndex index)
+ public static bool? IsClustered([NotNull] this IReadOnlyIndex index)
=> (bool?)index[SqlServerAnnotationNames.Clustered];
///
@@ -31,7 +31,7 @@ public static class SqlServerIndexExtensions
/// The index.
/// The identifier of the store object.
/// if the index is clustered.
- public static bool? IsClustered([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
+ public static bool? IsClustered([NotNull] this IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
{
var annotation = index.FindAnnotation(SqlServerAnnotationNames.Clustered);
if (annotation != null)
@@ -42,7 +42,7 @@ public static class SqlServerIndexExtensions
return GetDefaultIsClustered(index, storeObject);
}
- private static bool? GetDefaultIsClustered([NotNull] IIndex index, in StoreObjectIdentifier storeObject)
+ private static bool? GetDefaultIsClustered([NotNull] IReadOnlyIndex index, in StoreObjectIdentifier storeObject)
{
var sharedTableRootIndex = index.FindSharedObjectRootIndex(storeObject);
return sharedTableRootIndex?.IsClustered(storeObject);
@@ -91,7 +91,7 @@ public static void SetIsClustered([NotNull] this IMutableIndex index, bool? valu
///
/// The index.
/// The included property names, or if they have not been specified.
- public static IReadOnlyList? GetIncludeProperties([NotNull] this IIndex index)
+ public static IReadOnlyList? GetIncludeProperties([NotNull] this IReadOnlyIndex index)
=> (string[]?)index[SqlServerAnnotationNames.Include];
///
@@ -137,7 +137,7 @@ public static void SetIncludeProperties([NotNull] this IMutableIndex index, [Not
///
/// The index.
/// if the index is online.
- public static bool? IsCreatedOnline([NotNull] this IIndex index)
+ public static bool? IsCreatedOnline([NotNull] this IReadOnlyIndex index)
=> (bool?)index[SqlServerAnnotationNames.CreatedOnline];
///
@@ -183,7 +183,7 @@ public static void SetIsCreatedOnline([NotNull] this IMutableIndex index, bool?
///
/// The index.
/// if the index is online.
- public static int? GetFillFactor([NotNull] this IIndex index)
+ public static int? GetFillFactor([NotNull] this IReadOnlyIndex index)
=> (int?)index[SqlServerAnnotationNames.FillFactor];
///
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
index 1e37cdef8dc..70f35eabda8 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
@@ -11,7 +11,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for SQL Server-specific metadata.
+ /// Key extension methods for SQL Server-specific metadata.
///
public static class SqlServerKeyExtensions
{
@@ -20,7 +20,7 @@ public static class SqlServerKeyExtensions
///
/// The key.
/// if the key is clustered.
- public static bool? IsClustered([NotNull] this IKey key)
+ public static bool? IsClustered([NotNull] this IReadOnlyKey key)
=> (bool?)key[SqlServerAnnotationNames.Clustered];
///
@@ -29,7 +29,7 @@ public static class SqlServerKeyExtensions
/// The key.
/// The identifier of the store object.
/// if the key is clustered.
- public static bool? IsClustered([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
+ public static bool? IsClustered([NotNull] this IReadOnlyKey key, in StoreObjectIdentifier storeObject)
{
var annotation = key.FindAnnotation(SqlServerAnnotationNames.Clustered);
if (annotation != null)
@@ -40,7 +40,7 @@ public static class SqlServerKeyExtensions
return GetDefaultIsClustered(key, storeObject);
}
- private static bool? GetDefaultIsClustered([NotNull] IKey key, in StoreObjectIdentifier storeObject)
+ private static bool? GetDefaultIsClustered([NotNull] IReadOnlyKey key, in StoreObjectIdentifier storeObject)
{
var sharedTableRootKey = key.FindSharedObjectRootKey(storeObject);
return sharedTableRootKey?.IsClustered(storeObject);
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs
index 682f49a3897..9129259dca9 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for SQL Server-specific metadata.
+ /// Model extension methods for SQL Server-specific metadata.
///
public static class SqlServerModelExtensions
{
@@ -26,7 +26,7 @@ public static class SqlServerModelExtensions
///
/// The model.
/// The name to use for the default hi-lo sequence.
- public static string GetHiLoSequenceName([NotNull] this IModel model)
+ public static string GetHiLoSequenceName([NotNull] this IReadOnlyModel model)
=> (string?)model[SqlServerAnnotationNames.HiLoSequenceName]
?? DefaultHiLoSequenceName;
@@ -75,7 +75,7 @@ public static void SetHiLoSequenceName([NotNull] this IMutableModel model, [CanB
///
/// The model.
/// The schema to use for the default hi-lo sequence.
- public static string? GetHiLoSequenceSchema([NotNull] this IModel model)
+ public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyModel model)
=> (string?)model[SqlServerAnnotationNames.HiLoSequenceSchema];
///
@@ -122,7 +122,7 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableModel model, [Ca
///
/// The model.
/// The default identity seed.
- public static int GetIdentitySeed([NotNull] this IModel model)
+ public static int GetIdentitySeed([NotNull] this IReadOnlyModel model)
=> (int?)model[SqlServerAnnotationNames.IdentitySeed] ?? 1;
///
@@ -165,7 +165,7 @@ public static void SetIdentitySeed([NotNull] this IMutableModel model, int? seed
///
/// The model.
/// The default identity increment.
- public static int GetIdentityIncrement([NotNull] this IModel model)
+ public static int GetIdentityIncrement([NotNull] this IReadOnlyModel model)
=> (int?)model[SqlServerAnnotationNames.IdentityIncrement] ?? 1;
///
@@ -212,7 +212,7 @@ public static void SetIdentityIncrement([NotNull] this IMutableModel model, int?
///
/// The model.
/// The default .
- public static SqlServerValueGenerationStrategy? GetValueGenerationStrategy([NotNull] this IModel model)
+ public static SqlServerValueGenerationStrategy? GetValueGenerationStrategy([NotNull] this IReadOnlyModel model)
=> (SqlServerValueGenerationStrategy?)model[SqlServerAnnotationNames.ValueGenerationStrategy];
///
@@ -257,7 +257,7 @@ public static void SetValueGenerationStrategy(
///
/// The model.
/// The maximum size of the database.
- public static string? GetDatabaseMaxSize([NotNull] this IModel model)
+ public static string? GetDatabaseMaxSize([NotNull] this IReadOnlyModel model)
=> (string?)model[SqlServerAnnotationNames.MaxDatabaseSize];
///
@@ -298,7 +298,7 @@ public static void SetDatabaseMaxSize([NotNull] this IMutableModel model, [CanBe
///
/// The model.
/// The service tier of the database.
- public static string? GetServiceTierSql([NotNull] this IModel model)
+ public static string? GetServiceTierSql([NotNull] this IReadOnlyModel model)
=> (string?)model[SqlServerAnnotationNames.ServiceTierSql];
///
@@ -339,7 +339,7 @@ public static void SetServiceTierSql([NotNull] this IMutableModel model, [CanBeN
///
/// The model.
/// The performance level of the database.
- public static string? GetPerformanceLevelSql([NotNull] this IModel model)
+ public static string? GetPerformanceLevelSql([NotNull] this IReadOnlyModel model)
=> (string?)model[SqlServerAnnotationNames.PerformanceLevelSql];
///
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
index 9a77ec3c28d..648d8ecf9af 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
@@ -6,7 +6,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.SqlServer.Internal;
using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Storage;
@@ -18,7 +17,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for for SQL Server-specific metadata.
+ /// Property extension methods for SQL Server-specific metadata.
///
public static class SqlServerPropertyExtensions
{
@@ -27,7 +26,7 @@ public static class SqlServerPropertyExtensions
///
/// The property.
/// The name to use for the hi-lo sequence.
- public static string? GetHiLoSequenceName([NotNull] this IProperty property)
+ public static string? GetHiLoSequenceName([NotNull] this IReadOnlyProperty property)
=> (string?)property[SqlServerAnnotationNames.HiLoSequenceName];
///
@@ -36,7 +35,7 @@ public static class SqlServerPropertyExtensions
/// The property.
/// The identifier of the store object.
/// The name to use for the hi-lo sequence.
- public static string? GetHiLoSequenceName([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetHiLoSequenceName([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.HiLoSequenceName);
if (annotation != null)
@@ -93,7 +92,7 @@ public static void SetHiLoSequenceName([NotNull] this IMutableProperty property,
///
/// The property.
/// The schema to use for the hi-lo sequence.
- public static string? GetHiLoSequenceSchema([NotNull] this IProperty property)
+ public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property)
=> (string?)property[SqlServerAnnotationNames.HiLoSequenceSchema];
///
@@ -102,7 +101,7 @@ public static void SetHiLoSequenceName([NotNull] this IMutableProperty property,
/// The property.
/// The identifier of the store object.
/// The schema to use for the hi-lo sequence.
- public static string? GetHiLoSequenceSchema([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.HiLoSequenceSchema);
if (annotation != null)
@@ -159,7 +158,7 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty propert
///
/// The property.
/// The sequence to use, or if no sequence exists in the model.
- public static ISequence? FindHiLoSequence([NotNull] this IProperty property)
+ public static IReadOnlySequence? FindHiLoSequence([NotNull] this IReadOnlyProperty property)
{
var model = property.DeclaringEntityType.Model;
@@ -178,7 +177,7 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty propert
/// The property.
/// The identifier of the store object.
/// The sequence to use, or if no sequence exists in the model.
- public static ISequence? FindHiLoSequence([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static IReadOnlySequence? FindHiLoSequence([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var model = property.DeclaringEntityType.Model;
@@ -191,12 +190,29 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty propert
return model.FindSequence(sequenceName, sequenceSchema);
}
+ ///
+ /// Finds the in the model to use for the hi-lo pattern.
+ ///
+ /// The property.
+ /// The sequence to use, or if no sequence exists in the model.
+ public static ISequence? FindHiLoSequence([NotNull] this IProperty property)
+ => (ISequence?)((IReadOnlyProperty)property).FindHiLoSequence();
+
+ ///
+ /// Finds the in the model to use for the hi-lo pattern.
+ ///
+ /// The property.
+ /// The identifier of the store object.
+ /// The sequence to use, or if no sequence exists in the model.
+ public static ISequence? FindHiLoSequence([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ => (ISequence?)((IReadOnlyProperty)property).FindHiLoSequence(storeObject);
+
///
/// Returns the identity seed.
///
/// The property.
/// The identity seed.
- public static int? GetIdentitySeed([NotNull] this IProperty property)
+ public static int? GetIdentitySeed([NotNull] this IReadOnlyProperty property)
=> (int?)property[SqlServerAnnotationNames.IdentitySeed];
///
@@ -205,7 +221,7 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty propert
/// The property.
/// The identifier of the store object.
/// The identity seed.
- public static int? GetIdentitySeed([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static int? GetIdentitySeed([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.IdentitySeed);
if (annotation != null)
@@ -262,7 +278,7 @@ public static void SetIdentitySeed([NotNull] this IMutableProperty property, int
///
/// The property.
/// The identity increment.
- public static int? GetIdentityIncrement([NotNull] this IProperty property)
+ public static int? GetIdentityIncrement([NotNull] this IReadOnlyProperty property)
=> (int?)property[SqlServerAnnotationNames.IdentityIncrement];
///
@@ -271,7 +287,7 @@ public static void SetIdentitySeed([NotNull] this IMutableProperty property, int
/// The property.
/// The identifier of the store object.
/// The identity increment.
- public static int? GetIdentityIncrement([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
+ public static int? GetIdentityIncrement([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.IdentityIncrement);
if (annotation != null)
@@ -333,7 +349,7 @@ public static void SetIdentityIncrement([NotNull] this IMutableProperty property
///
/// The property.
/// The strategy, or if none was set.
- public static SqlServerValueGenerationStrategy GetValueGenerationStrategy([NotNull] this IProperty property)
+ public static SqlServerValueGenerationStrategy GetValueGenerationStrategy([NotNull] this IReadOnlyProperty property)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy);
if (annotation != null)
@@ -365,12 +381,12 @@ public static SqlServerValueGenerationStrategy GetValueGenerationStrategy([NotNu
/// The identifier of the store object.
/// The strategy, or if none was set.
public static SqlServerValueGenerationStrategy GetValueGenerationStrategy(
- [NotNull] this IProperty property,
+ [NotNull] this IReadOnlyProperty property,
in StoreObjectIdentifier storeObject)
=> GetValueGenerationStrategy(property, storeObject, null);
internal static SqlServerValueGenerationStrategy GetValueGenerationStrategy(
- [NotNull] this IProperty property,
+ [NotNull] this IReadOnlyProperty property,
in StoreObjectIdentifier storeObject,
ITypeMappingSource? typeMappingSource)
{
@@ -402,7 +418,7 @@ internal static SqlServerValueGenerationStrategy GetValueGenerationStrategy(
return GetDefaultValueGenerationStrategy(property, storeObject, typeMappingSource);
}
- private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrategy(IProperty property)
+ private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrategy(IReadOnlyProperty property)
{
var modelStrategy = property.DeclaringEntityType.Model.GetValueGenerationStrategy();
@@ -419,7 +435,7 @@ private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrateg
}
private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrategy(
- IProperty property,
+ IReadOnlyProperty property,
in StoreObjectIdentifier storeObject,
ITypeMappingSource? typeMappingSource)
{
@@ -470,7 +486,7 @@ public static void SetValueGenerationStrategy(
return value;
}
- private static void CheckValueGenerationStrategy(IProperty property, SqlServerValueGenerationStrategy? value)
+ private static void CheckValueGenerationStrategy(IReadOnlyProperty property, SqlServerValueGenerationStrategy? value)
{
if (value != null)
{
@@ -508,7 +524,7 @@ private static void CheckValueGenerationStrategy(IProperty property, SqlServerVa
///
/// The property.
/// if compatible.
- public static bool IsCompatibleWithValueGeneration([NotNull] IProperty property)
+ public static bool IsCompatibleWithValueGeneration([NotNull] IReadOnlyProperty property)
{
var type = property.ClrType;
@@ -520,7 +536,7 @@ public static bool IsCompatibleWithValueGeneration([NotNull] IProperty property)
}
private static bool IsCompatibleWithValueGeneration(
- [NotNull] IProperty property,
+ [NotNull] IReadOnlyProperty property,
in StoreObjectIdentifier storeObject,
ITypeMappingSource? typeMappingSource)
{
@@ -530,7 +546,7 @@ private static bool IsCompatibleWithValueGeneration(
|| type == typeof(decimal))
&& (property.GetValueConverter()
?? (property.FindRelationalTypeMapping(storeObject)
- ?? typeMappingSource?.FindMapping(property))?.Converter)
+ ?? typeMappingSource?.FindMapping((IProperty)property))?.Converter)
== null;
}
@@ -539,7 +555,7 @@ private static bool IsCompatibleWithValueGeneration(
///
/// The property.
/// if the property's column is sparse.
- public static bool? IsSparse([NotNull] this IProperty property)
+ public static bool? IsSparse([NotNull] this IReadOnlyProperty property)
=> (bool?)property[SqlServerAnnotationNames.Sparse];
///
diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs
index 6fea8048f6e..acefe5538e3 100644
--- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs
+++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs
@@ -93,12 +93,12 @@ protected virtual void ValidateDecimalColumns(
&& (ConfigurationSource.Convention.Overrides(property.GetPrecisionConfigurationSource())
|| ConfigurationSource.Convention.Overrides(property.GetScaleConfigurationSource())))
{
- logger.DecimalTypeDefaultWarning(property);
+ logger.DecimalTypeDefaultWarning((IProperty)property);
}
if (property.IsKey())
{
- logger.DecimalTypeKeyWarning(property);
+ logger.DecimalTypeKeyWarning((IProperty)property);
}
}
}
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs
index d6fef269e6a..33a7dd60188 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs
@@ -12,8 +12,8 @@
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
///
- /// A convention that ensures that is populated for database functions which
- /// have flag set to .
+ /// A convention that ensures that is populated for database functions which
+ /// have flag set to .
///
public class SqlServerDbFunctionConvention : IModelFinalizingConvention
{
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs
index 71752d77e12..5790a995b99 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs
@@ -194,7 +194,7 @@ private string CreateIndexFilter(List nullableColumns)
return builder.ToString();
}
- private List? GetNullableColumns(IIndex index)
+ private List? GetNullableColumns(IReadOnlyIndex index)
{
var tableName = index.DeclaringEntityType.GetTableName();
if (tableName == null)
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
index ff4c02aca92..b9ecad244ed 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
@@ -28,12 +28,12 @@ public SqlServerSharedTableConvention(
}
///
- protected override bool AreCompatible(IKey key, IKey duplicateKey, in StoreObjectIdentifier storeObject)
+ protected override bool AreCompatible(IReadOnlyKey key, IReadOnlyKey duplicateKey, in StoreObjectIdentifier storeObject)
=> base.AreCompatible(key, duplicateKey, storeObject)
&& key.AreCompatibleForSqlServer(duplicateKey, storeObject, shouldThrow: false);
///
- protected override bool AreCompatible(IIndex index, IIndex duplicateIndex, in StoreObjectIdentifier storeObject)
+ protected override bool AreCompatible(IReadOnlyIndex index, IReadOnlyIndex duplicateIndex, in StoreObjectIdentifier storeObject)
=> base.AreCompatible(index, duplicateIndex, storeObject)
&& index.AreCompatibleForSqlServer(duplicateIndex, storeObject, shouldThrow: false);
}
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
index 81bca81262e..6a3d673de21 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
@@ -81,14 +81,14 @@ public override void ProcessPropertyAnnotationChanged(
/// The property.
/// The identifier of the store object.
/// The store value generation strategy to set for the given property.
- public static new ValueGenerated? GetValueGenerated([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
+ public static new ValueGenerated? GetValueGenerated([NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
=> RelationalValueGenerationConvention.GetValueGenerated(property, storeObject)
?? (property.GetValueGenerationStrategy(storeObject) != SqlServerValueGenerationStrategy.None
? ValueGenerated.OnAdd
: (ValueGenerated?)null);
private ValueGenerated? GetValueGenerated(
- [NotNull] IProperty property,
+ [NotNull] IReadOnlyProperty property,
in StoreObjectIdentifier storeObject,
ITypeMappingSource typeMappingSource)
=> RelationalValueGenerationConvention.GetValueGenerated(property, storeObject)
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs
index 32d85583843..a8ee05d9c18 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs
@@ -87,7 +87,7 @@ public virtual void ProcessModelFinalizing(
}
}
- bool IsStrategyNoneNeeded(IProperty property, StoreObjectIdentifier storeObject)
+ bool IsStrategyNoneNeeded(IReadOnlyProperty property, StoreObjectIdentifier storeObject)
{
if (property.ValueGenerated == ValueGenerated.OnAdd
&& property.GetDefaultValue(storeObject) == null
@@ -97,7 +97,7 @@ bool IsStrategyNoneNeeded(IProperty property, StoreObjectIdentifier storeObject)
{
var providerClrType = (property.GetValueConverter()
?? (property.FindRelationalTypeMapping(storeObject)
- ?? Dependencies.TypeMappingSource.FindMapping(property))?.Converter)
+ ?? Dependencies.TypeMappingSource.FindMapping((IProperty)property))?.Converter)
?.ProviderClrType.UnwrapNullableType();
return providerClrType != null
diff --git a/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs b/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
index 1dd76a2f41a..7f2d8f31021 100644
--- a/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
+++ b/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
@@ -25,8 +25,8 @@ public static class SqlServerIndexExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatibleForSqlServer(
- [NotNull] this IIndex index,
- [NotNull] IIndex duplicateIndex,
+ [NotNull] this IReadOnlyIndex index,
+ [NotNull] IReadOnlyIndex duplicateIndex,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
@@ -107,7 +107,7 @@ public static bool AreCompatibleForSqlServer(
return true;
- static bool SameColumnNames(IIndex index, IIndex duplicateIndex, StoreObjectIdentifier storeObject)
+ static bool SameColumnNames(IReadOnlyIndex index, IReadOnlyIndex duplicateIndex, StoreObjectIdentifier storeObject)
=> index.GetIncludeProperties()!.Select(
p => index.DeclaringEntityType.FindProperty(p)!.GetColumnName(storeObject))
.SequenceEqual(
@@ -115,7 +115,7 @@ static bool SameColumnNames(IIndex index, IIndex duplicateIndex, StoreObjectIden
p => duplicateIndex.DeclaringEntityType.FindProperty(p)!.GetColumnName(storeObject)));
}
- private static string FormatInclude(IIndex index, StoreObjectIdentifier storeObject)
+ private static string FormatInclude(IReadOnlyIndex index, StoreObjectIdentifier storeObject)
=> index.GetIncludeProperties() == null
? "{}"
: "{'"
diff --git a/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs b/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
index 705c0b4e073..78d8af7852d 100644
--- a/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
+++ b/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
@@ -24,8 +24,8 @@ public static class SqlServerKeyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatibleForSqlServer(
- [NotNull] this IKey key,
- [NotNull] IKey duplicateKey,
+ [NotNull] this IReadOnlyKey key,
+ [NotNull] IReadOnlyKey duplicateKey,
in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs
index ebdaa02b1fa..0a478918bd7 100644
--- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs
+++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs
@@ -8,6 +8,7 @@
using System.Transactions;
using JetBrains.Annotations;
using Microsoft.Data.SqlClient;
+using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.SqlServer.Internal;
@@ -182,7 +183,8 @@ private IReadOnlyList CreateCreateOperations()
FileName = builder.AttachDBFilename,
Collation = Dependencies.Model.GetCollation()
}
- });
+ },
+ null);
}
///
@@ -389,7 +391,7 @@ private IReadOnlyList CreateDropCommands()
var operations = new MigrationOperation[] { new SqlServerDropDatabaseOperation { Name = databaseName } };
- return Dependencies.MigrationsSqlGenerator.Generate(operations);
+ return Dependencies.MigrationsSqlGenerator.Generate(operations, null);
}
// Clear connection pools in case there are active connections that are pooled
diff --git a/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs
index 9985e4d90b6..f03fa06db31 100644
--- a/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs
+++ b/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs
@@ -65,7 +65,7 @@ private static string SchemaConfiguredWarning(EventDefinitionBase definition, Ev
///
public static void SequenceConfiguredWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] ISequence sequence)
+ [NotNull] IReadOnlySequence sequence)
{
var definition = SqliteResources.LogSequenceConfigured(diagnostics);
diff --git a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
index 47c0737aaf2..2ef7d155b28 100644
--- a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
+++ b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
@@ -20,7 +20,7 @@ public static class SqlitePropertyExtensions
///
/// The property.
/// The SRID to use when creating a column for this property.
- public static int? GetSrid([NotNull] this IProperty property)
+ public static int? GetSrid([NotNull] this IReadOnlyProperty property)
=> (int?)property[SqliteAnnotationNames.Srid];
///
@@ -30,7 +30,7 @@ public static class SqlitePropertyExtensions
/// The identifier of the store object.
/// The SRID to use when creating a column for this property.
public static int? GetSrid(
- [NotNull] this IProperty property,
+ [NotNull] this IReadOnlyProperty property,
in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqliteAnnotationNames.Srid);
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
index 016529664cf..309e4fed4a1 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
@@ -23,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
///
public class SqliteRegexMethodTranslator : IMethodCallTranslator
{
- private readonly static MethodInfo _regexIsMatchMethodInfo
+ private static readonly MethodInfo _regexIsMatchMethodInfo
= typeof(Regex).GetRequiredRuntimeMethod(nameof(Regex.IsMatch), new Type[] { typeof(string), typeof(string) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs
index 3a15368e0d9..9796a9c98c2 100644
--- a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs
+++ b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs
@@ -64,7 +64,7 @@ public override void SetValues(object obj)
{
if (!Properties[i].IsShadowProperty())
{
- SetValue(i, ((Property)Properties[i]).Getter.GetClrValue(obj));
+ SetValue(i, Properties[i].GetGetter().GetClrValue(obj));
}
}
}
diff --git a/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs
index d153f5992a3..7d0515ef623 100644
--- a/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs
+++ b/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs
@@ -57,7 +57,7 @@ public override void SetValues(object obj)
{
foreach (var property in Properties.Where(p => !p.IsShadowProperty()))
{
- SetValueInternal(property, ((Property)property).Getter.GetClrValue(obj));
+ SetValueInternal(property, property.GetGetter().GetClrValue(obj));
}
}
else
diff --git a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs
index ff260eb0677..0e77f5a37d6 100644
--- a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs
+++ b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs
@@ -47,7 +47,7 @@ public IdentityMap(
{
_foreignKeys = key.DeclaringEntityType
.GetDerivedTypesInclusive()
- .SelectMany(EntityTypeExtensions.GetDeclaredForeignKeys)
+ .SelectMany(t => t.GetDeclaredForeignKeys())
.ToArray();
}
}
diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
index e33f16faf63..73f5ddcc722 100644
--- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
+++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
@@ -743,7 +743,7 @@ protected virtual object ReadPropertyValue([NotNull] IPropertyBase propertyBase)
{
Check.DebugAssert(!propertyBase.IsShadowProperty(), "propertyBase is shadow property");
- return ((PropertyBase)propertyBase).Getter.GetClrValue(Entity);
+ return propertyBase.GetGetter().GetClrValue(Entity);
}
///
@@ -756,7 +756,7 @@ protected virtual bool PropertyHasDefaultValue([NotNull] IPropertyBase propertyB
{
Check.DebugAssert(!propertyBase.IsShadowProperty(), "propertyBase is shadow property");
- return ((PropertyBase)propertyBase).Getter.HasDefaultValue(Entity);
+ return propertyBase.GetGetter().HasDefaultValue(Entity);
}
///
@@ -1620,7 +1620,7 @@ public virtual void HandleINotifyPropertyChanging(
[NotNull] object sender,
[NotNull] PropertyChangingEventArgs eventArgs)
{
- foreach (var propertyBase in EntityType.GetNotificationProperties(eventArgs.PropertyName))
+ foreach (var propertyBase in GetNotificationProperties(EntityType, eventArgs.PropertyName))
{
StateManager.InternalEntityEntryNotifier.PropertyChanging(this, propertyBase);
}
@@ -1636,12 +1636,48 @@ public virtual void HandleINotifyPropertyChanged(
[NotNull] object sender,
[NotNull] PropertyChangedEventArgs eventArgs)
{
- foreach (var propertyBase in EntityType.GetNotificationProperties(eventArgs.PropertyName))
+ foreach (var propertyBase in GetNotificationProperties(EntityType, eventArgs.PropertyName))
{
StateManager.InternalEntityEntryNotifier.PropertyChanged(this, propertyBase, setModified: true);
}
}
+ private static IEnumerable GetNotificationProperties(
+ [NotNull] IEntityType entityType,
+ [CanBeNull] string propertyName)
+ {
+ if (string.IsNullOrEmpty(propertyName))
+ {
+ foreach (var property in entityType.GetProperties()
+ .Where(p => p.GetAfterSaveBehavior() == PropertySaveBehavior.Save))
+ {
+ yield return property;
+ }
+
+ foreach (var navigation in entityType.GetNavigations())
+ {
+ yield return navigation;
+ }
+
+ foreach (var navigation in entityType.GetSkipNavigations())
+ {
+ yield return navigation;
+ }
+ }
+ else
+ {
+ // ReSharper disable once AssignNullToNotNullAttribute
+ var property = entityType.FindProperty(propertyName)
+ ?? entityType.FindNavigation(propertyName)
+ ?? (IPropertyBase)entityType.FindSkipNavigation(propertyName);
+
+ if (property != null)
+ {
+ yield return property;
+ }
+ }
+ }
+
///
/// 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
diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs
index 1076a671f64..f77f9ace9c4 100644
--- a/src/EFCore/ChangeTracking/Internal/StateManager.cs
+++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs
@@ -177,8 +177,7 @@ public virtual void StateChanging(InternalEntityEntry entry, EntityState newStat
/// 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 IModel Model
- => _model;
+ public virtual IModel Model => _model;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs
index 32582267b9e..0ce41b284a5 100644
--- a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs
+++ b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs
@@ -61,7 +61,7 @@ public ValueGenerationManager(
public virtual InternalEntityEntry Propagate(InternalEntityEntry entry)
{
InternalEntityEntry chosenPrincipal = null;
- foreach (var property in FindCandidatePropagatingProperties(entry))
+ foreach (var property in entry.EntityType.GetForeignKeyProperties())
{
if (!entry.HasDefaultValue(property))
{
@@ -88,7 +88,7 @@ public virtual void Generate(InternalEntityEntry entry, bool includePrimaryKey =
{
var entityEntry = new EntityEntry(entry);
- foreach (var property in FindCandidateGeneratingProperties(entry))
+ foreach (var property in entry.EntityType.GetValueGeneratingProperties())
{
if (!entry.HasDefaultValue(property)
|| (!includePrimaryKey
@@ -137,7 +137,7 @@ public virtual async Task GenerateAsync(
{
var entityEntry = new EntityEntry(entry);
- foreach (var property in FindCandidateGeneratingProperties(entry))
+ foreach (var property in entry.EntityType.GetValueGeneratingProperties())
{
if (!entry.HasDefaultValue(property)
|| (!includePrimaryKey
@@ -161,12 +161,6 @@ public virtual async Task GenerateAsync(
}
}
- private IReadOnlyList FindCandidatePropagatingProperties(InternalEntityEntry entry)
- => entry.EntityType.GetPropagatingProperties();
-
- private IReadOnlyList FindCandidateGeneratingProperties(InternalEntityEntry entry)
- => entry.EntityType.GetGeneratingProperties();
-
private ValueGenerator GetValueGenerator(InternalEntityEntry entry, IProperty property)
=> _valueGeneratorSelector.Select(
property, property.IsKey()
diff --git a/src/EFCore/Diagnostics/CollectionChangedEventData.cs b/src/EFCore/Diagnostics/CollectionChangedEventData.cs
index 1f0e97aefa9..c2e068f6fa7 100644
--- a/src/EFCore/Diagnostics/CollectionChangedEventData.cs
+++ b/src/EFCore/Diagnostics/CollectionChangedEventData.cs
@@ -50,6 +50,11 @@ public CollectionChangedEventData(
///
public virtual EntityEntry EntityEntry { get; }
+ ///
+ /// The navigation.
+ ///
+ public new virtual INavigation Navigation => (INavigation)base.Navigation;
+
///
/// The entities added to the collection.
///
diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs
index b34d4bd5053..0d2acd34fca 100644
--- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs
+++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs
@@ -1081,8 +1081,8 @@ private static string CollectionWithoutComparer(EventDefinitionBase definition,
/// The other index.
public static void RedundantIndexRemoved(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] IReadOnlyList redundantIndex,
- [NotNull] IReadOnlyList otherIndex)
+ [NotNull] IReadOnlyList redundantIndex,
+ [NotNull] IReadOnlyList otherIndex)
{
var definition = CoreResources.LogRedundantIndexRemoved(diagnostics);
@@ -1174,8 +1174,8 @@ public static void IncompatibleMatchingForeignKeyProperties(
[NotNull] this IDiagnosticsLogger diagnostics,
[NotNull] string dependentToPrincipalNavigationSpecification,
[NotNull] string principalToDependentNavigationSpecification,
- [NotNull] IReadOnlyList foreignKeyProperties,
- [NotNull] IReadOnlyList principalKeyProperties)
+ [NotNull] IReadOnlyList foreignKeyProperties,
+ [NotNull] IReadOnlyList principalKeyProperties)
{
var definition = CoreResources.LogIncompatibleMatchingForeignKeyProperties(diagnostics);
@@ -1334,8 +1334,8 @@ private static string NonNullableInverted(EventDefinitionBase definition, EventD
[Obsolete]
public static void RequiredAttributeOnBothNavigations(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation firstNavigation,
- [NotNull] INavigation secondNavigation)
+ [NotNull] IReadOnlyNavigation firstNavigation,
+ [NotNull] IReadOnlyNavigation secondNavigation)
{
var definition = CoreResources.LogRequiredAttributeOnBothNavigations(diagnostics);
@@ -1384,8 +1384,8 @@ private static string RequiredAttributeOnBothNavigations(EventDefinitionBase def
[Obsolete]
public static void NonNullableReferenceOnBothNavigations(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation firstNavigation,
- [NotNull] INavigation secondNavigation)
+ [NotNull] IReadOnlyNavigation firstNavigation,
+ [NotNull] IReadOnlyNavigation secondNavigation)
{
var definition = CoreResources.LogNonNullableReferenceOnBothNavigations(diagnostics);
@@ -1509,7 +1509,7 @@ private static string NonNullableReferenceOnDependent(EventDefinitionBase defini
/// The navigation property.
public static void RequiredAttributeOnCollection(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation navigation)
+ [NotNull] IReadOnlyNavigation navigation)
{
var definition = CoreResources.LogRequiredAttributeOnCollection(diagnostics);
@@ -1543,7 +1543,7 @@ private static string RequiredAttributeOnCollection(EventDefinitionBase definiti
/// The navigation property.
public static void RequiredAttributeOnSkipNavigation(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] ISkipNavigation navigation)
+ [NotNull] IReadOnlySkipNavigation navigation)
{
var definition = CoreResources.LogRequiredAttributeOnSkipNavigation(diagnostics);
@@ -1577,7 +1577,7 @@ private static string RequiredAttributeOnSkipNavigation(EventDefinitionBase defi
/// The foreign key.
public static void ConflictingShadowForeignKeysWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] IForeignKey foreignKey)
+ [NotNull] IReadOnlyForeignKey foreignKey)
{
var definition = CoreResources.LogConflictingShadowForeignKeys(diagnostics);
@@ -1620,8 +1620,8 @@ private static string ConflictingShadowForeignKeysWarning(EventDefinitionBase de
/// The second property.
public static void MultiplePrimaryKeyCandidates(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] IProperty firstProperty,
- [NotNull] IProperty secondProperty)
+ [NotNull] IReadOnlyProperty firstProperty,
+ [NotNull] IReadOnlyProperty secondProperty)
{
var definition = CoreResources.LogMultiplePrimaryKeyCandidates(diagnostics);
@@ -1822,9 +1822,9 @@ private static string NonDefiningInverseNavigationWarning(EventDefinitionBase de
/// The ownership navigation property.
public static void NonOwnershipInverseNavigationWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] IEntityType declaringType,
+ [NotNull] IReadOnlyEntityType declaringType,
[NotNull] MemberInfo navigation,
- [NotNull] IEntityType targetType,
+ [NotNull] IReadOnlyEntityType targetType,
[NotNull] MemberInfo inverseNavigation,
[NotNull] MemberInfo ownershipNavigation)
{
@@ -1882,8 +1882,8 @@ private static string NonOwnershipInverseNavigationWarning(EventDefinitionBase d
/// The second property.
public static void ForeignKeyAttributesOnBothPropertiesWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation firstNavigation,
- [NotNull] INavigation secondNavigation,
+ [NotNull] IReadOnlyNavigation firstNavigation,
+ [NotNull] IReadOnlyNavigation secondNavigation,
[NotNull] MemberInfo firstProperty,
[NotNull] MemberInfo secondProperty)
{
@@ -1948,8 +1948,8 @@ private static string ForeignKeyAttributesOnBothPropertiesWarning(EventDefinitio
/// The second navigation property.
public static void ForeignKeyAttributesOnBothNavigationsWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation firstNavigation,
- [NotNull] INavigation secondNavigation)
+ [NotNull] IReadOnlyNavigation firstNavigation,
+ [NotNull] IReadOnlyNavigation secondNavigation)
{
var definition = CoreResources.LogForeignKeyAttributesOnBothNavigations(diagnostics);
@@ -1996,7 +1996,7 @@ private static string ForeignKeyAttributesOnBothNavigationsWarning(EventDefiniti
/// The property.
public static void ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] INavigation navigation,
+ [NotNull] IReadOnlyNavigation navigation,
[NotNull] MemberInfo property)
{
var definition = CoreResources.LogConflictingForeignKeyAttributesOnNavigationAndProperty(diagnostics);
@@ -3311,7 +3311,7 @@ private static string ContextDisposed(EventDefinitionBase definition, EventData
/// The property which is being defined as part of a key.
public static void ConflictingKeylessAndKeyAttributesWarning(
[NotNull] this IDiagnosticsLogger diagnostics,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
{
var definition = CoreResources.LogConflictingKeylessAndKeyAttributes(diagnostics);
diff --git a/src/EFCore/Diagnostics/ForeignKeyCandidateEventData.cs b/src/EFCore/Diagnostics/ForeignKeyCandidateEventData.cs
index cbb49f78099..74e9fbcdaf1 100644
--- a/src/EFCore/Diagnostics/ForeignKeyCandidateEventData.cs
+++ b/src/EFCore/Diagnostics/ForeignKeyCandidateEventData.cs
@@ -35,8 +35,8 @@ public ForeignKeyCandidateEventData(
[NotNull] Func messageGenerator,
[NotNull] string dependentToPrincipalNavigationSpecification,
[NotNull] string principalToDependentNavigationSpecification,
- [NotNull] IReadOnlyList firstPropertyCollection,
- [NotNull] IReadOnlyList secondPropertyCollection)
+ [NotNull] IReadOnlyList firstPropertyCollection,
+ [NotNull] IReadOnlyList secondPropertyCollection)
: base(eventDefinition, messageGenerator, firstPropertyCollection, secondPropertyCollection)
{
DependentToPrincipalNavigationSpecification = dependentToPrincipalNavigationSpecification;
diff --git a/src/EFCore/Diagnostics/ForeignKeyEventData.cs b/src/EFCore/Diagnostics/ForeignKeyEventData.cs
index e219303b9f9..e4fc9bdaf5a 100644
--- a/src/EFCore/Diagnostics/ForeignKeyEventData.cs
+++ b/src/EFCore/Diagnostics/ForeignKeyEventData.cs
@@ -23,7 +23,7 @@ public class ForeignKeyEventData : EventData
public ForeignKeyEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] IForeignKey foreignKey)
+ [NotNull] IReadOnlyForeignKey foreignKey)
: base(eventDefinition, messageGenerator)
{
ForeignKey = foreignKey;
@@ -32,6 +32,6 @@ public ForeignKeyEventData(
///
/// The foreign key.
///
- public virtual IForeignKey ForeignKey { get; }
+ public virtual IReadOnlyForeignKey ForeignKey { get; }
}
}
diff --git a/src/EFCore/Diagnostics/NavigationBaseEventData.cs b/src/EFCore/Diagnostics/NavigationBaseEventData.cs
index f958891c99a..d8aa645b521 100644
--- a/src/EFCore/Diagnostics/NavigationBaseEventData.cs
+++ b/src/EFCore/Diagnostics/NavigationBaseEventData.cs
@@ -22,7 +22,7 @@ public class NavigationBaseEventData : EventData, INavigationBaseEventData
public NavigationBaseEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] INavigationBase navigationBase)
+ [NotNull] IReadOnlyNavigationBase navigationBase)
: base(eventDefinition, messageGenerator)
{
NavigationBase = navigationBase;
@@ -31,6 +31,9 @@ public NavigationBaseEventData(
///
/// The navigation base.
///
- public virtual INavigationBase NavigationBase { get; }
+ public virtual IReadOnlyNavigationBase NavigationBase { get; }
+
+ INavigationBase INavigationBaseEventData.NavigationBase
+ => (INavigationBase)NavigationBase;
}
}
diff --git a/src/EFCore/Diagnostics/NavigationEventData.cs b/src/EFCore/Diagnostics/NavigationEventData.cs
index 2d3c36e4ad4..e07508e2a07 100644
--- a/src/EFCore/Diagnostics/NavigationEventData.cs
+++ b/src/EFCore/Diagnostics/NavigationEventData.cs
@@ -22,7 +22,7 @@ public class NavigationEventData : EventData, INavigationBaseEventData
public NavigationEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] INavigation navigation)
+ [NotNull] IReadOnlyNavigation navigation)
: base(eventDefinition, messageGenerator)
{
Navigation = navigation;
@@ -31,12 +31,12 @@ public NavigationEventData(
///
/// The navigation.
///
- public virtual INavigation Navigation { get; }
+ public virtual IReadOnlyNavigation Navigation { get; }
///
/// The navigation.
///
INavigationBase INavigationBaseEventData.NavigationBase
- => Navigation;
+ => (INavigationBase)Navigation;
}
}
diff --git a/src/EFCore/Diagnostics/PropertyChangedEventData.cs b/src/EFCore/Diagnostics/PropertyChangedEventData.cs
index 657c2f27a30..544ece26f03 100644
--- a/src/EFCore/Diagnostics/PropertyChangedEventData.cs
+++ b/src/EFCore/Diagnostics/PropertyChangedEventData.cs
@@ -46,6 +46,11 @@ public PropertyChangedEventData(
///
public virtual EntityEntry EntityEntry { get; }
+ ///
+ /// The property.
+ ///
+ public new virtual IProperty Property => (IProperty)base.Property;
+
///
/// The old value.
///
diff --git a/src/EFCore/Diagnostics/PropertyEventData.cs b/src/EFCore/Diagnostics/PropertyEventData.cs
index c236c7ceacd..2401f957fd8 100644
--- a/src/EFCore/Diagnostics/PropertyEventData.cs
+++ b/src/EFCore/Diagnostics/PropertyEventData.cs
@@ -23,7 +23,7 @@ public class PropertyEventData : EventData
public PropertyEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
: base(eventDefinition, messageGenerator)
{
Property = property;
@@ -32,6 +32,6 @@ public PropertyEventData(
///
/// The property.
///
- public virtual IProperty Property { get; }
+ public virtual IReadOnlyProperty Property { get; }
}
}
diff --git a/src/EFCore/Diagnostics/PropertyValueEventData.cs b/src/EFCore/Diagnostics/PropertyValueEventData.cs
index 1dcd2b74522..48df93887e0 100644
--- a/src/EFCore/Diagnostics/PropertyValueEventData.cs
+++ b/src/EFCore/Diagnostics/PropertyValueEventData.cs
@@ -43,6 +43,11 @@ public PropertyValueEventData(
///
public virtual EntityEntry EntityEntry { get; }
+ ///
+ /// The property.
+ ///
+ public new virtual IProperty Property => (IProperty)base.Property;
+
///
/// The value.
///
diff --git a/src/EFCore/Diagnostics/ReferenceChangedEventData.cs b/src/EFCore/Diagnostics/ReferenceChangedEventData.cs
index d3a274c0776..7f243ff3e6b 100644
--- a/src/EFCore/Diagnostics/ReferenceChangedEventData.cs
+++ b/src/EFCore/Diagnostics/ReferenceChangedEventData.cs
@@ -46,6 +46,11 @@ public ReferenceChangedEventData(
///
public virtual EntityEntry EntityEntry { get; }
+ ///
+ /// The navigation.
+ ///
+ public new virtual INavigation Navigation => (INavigation)base.Navigation;
+
///
/// The old referenced entity.
///
diff --git a/src/EFCore/Diagnostics/SkipCollectionChangedEventData.cs b/src/EFCore/Diagnostics/SkipCollectionChangedEventData.cs
index e6f6de5d96b..18f893fd1e9 100644
--- a/src/EFCore/Diagnostics/SkipCollectionChangedEventData.cs
+++ b/src/EFCore/Diagnostics/SkipCollectionChangedEventData.cs
@@ -50,6 +50,11 @@ public SkipCollectionChangedEventData(
///
public virtual EntityEntry EntityEntry { get; }
+ ///
+ /// The navigation.
+ ///
+ public new virtual ISkipNavigation Navigation => (ISkipNavigation)base.Navigation;
+
///
/// The entities added to the collection.
///
diff --git a/src/EFCore/Diagnostics/SkipNavigationEventData.cs b/src/EFCore/Diagnostics/SkipNavigationEventData.cs
index 968f8c29c1d..89b6333395a 100644
--- a/src/EFCore/Diagnostics/SkipNavigationEventData.cs
+++ b/src/EFCore/Diagnostics/SkipNavigationEventData.cs
@@ -22,7 +22,7 @@ public class SkipNavigationEventData : EventData, INavigationBaseEventData
public SkipNavigationEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] ISkipNavigation navigation)
+ [NotNull] IReadOnlySkipNavigation navigation)
: base(eventDefinition, messageGenerator)
{
Navigation = navigation;
@@ -31,12 +31,12 @@ public SkipNavigationEventData(
///
/// The navigation.
///
- public virtual ISkipNavigation Navigation { get; }
+ public virtual IReadOnlySkipNavigation Navigation { get; }
///
/// The navigation.
///
INavigationBase INavigationBaseEventData.NavigationBase
- => Navigation;
+ => (INavigationBase)Navigation;
}
}
diff --git a/src/EFCore/Diagnostics/TwoPropertyBaseCollectionsEventData.cs b/src/EFCore/Diagnostics/TwoPropertyBaseCollectionsEventData.cs
index f77ff4f3ead..0f6ea5eab8f 100644
--- a/src/EFCore/Diagnostics/TwoPropertyBaseCollectionsEventData.cs
+++ b/src/EFCore/Diagnostics/TwoPropertyBaseCollectionsEventData.cs
@@ -25,8 +25,8 @@ public class TwoPropertyBaseCollectionsEventData : EventData
public TwoPropertyBaseCollectionsEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
- [NotNull] IReadOnlyList firstPropertyCollection,
- [NotNull] IReadOnlyList secondPropertyCollection)
+ [NotNull] IReadOnlyList firstPropertyCollection,
+ [NotNull] IReadOnlyList secondPropertyCollection)
: base(eventDefinition, messageGenerator)
{
FirstPropertyCollection = firstPropertyCollection;
@@ -36,11 +36,11 @@ public TwoPropertyBaseCollectionsEventData(
///
/// The first property collection.
///
- public virtual IReadOnlyList FirstPropertyCollection { get; }
+ public virtual IReadOnlyList FirstPropertyCollection { get; }
///
/// The second property collection.
///
- public virtual IReadOnlyList SecondPropertyCollection { get; }
+ public virtual IReadOnlyList SecondPropertyCollection { get; }
}
}
diff --git a/src/EFCore/Extensions/ConventionAnnotatableExtensions.cs b/src/EFCore/Extensions/ConventionAnnotatableExtensions.cs
index 4f8fd686513..52d15091077 100644
--- a/src/EFCore/Extensions/ConventionAnnotatableExtensions.cs
+++ b/src/EFCore/Extensions/ConventionAnnotatableExtensions.cs
@@ -26,7 +26,7 @@ public static class ConventionAnnotatableExtensions
public static IConventionAnnotation GetAnnotation(
[NotNull] this IConventionAnnotatable annotatable,
[NotNull] string annotationName)
- => (IConventionAnnotation)((IAnnotatable)annotatable).GetAnnotation(annotationName);
+ => (IConventionAnnotation)((IReadOnlyAnnotatable)annotatable).GetAnnotation(annotationName);
///
/// Adds annotations to an object.
diff --git a/src/EFCore/Extensions/ConventionEntityTypeExtensions.cs b/src/EFCore/Extensions/ConventionEntityTypeExtensions.cs
index 34f5113267c..f7322398e0c 100644
--- a/src/EFCore/Extensions/ConventionEntityTypeExtensions.cs
+++ b/src/EFCore/Extensions/ConventionEntityTypeExtensions.cs
@@ -32,7 +32,7 @@ public static class ConventionEntityTypeExtensions
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
///
public static IConventionEntityType GetRootType([NotNull] this IConventionEntityType entityType)
- => (IConventionEntityType)((IEntityType)entityType).GetRootType();
+ => (IConventionEntityType)((IReadOnlyEntityType)entityType).GetRootType();
///
/// Gets all types in the model from which a given entity type derives, starting with the root.
@@ -54,6 +54,14 @@ public static IEnumerable GetAllBaseTypes([NotNull] this
public static IEnumerable GetAllBaseTypesAscending([NotNull] this IConventionEntityType entityType)
=> entityType.GetAllBaseTypesInclusiveAscending().Skip(1);
+ ///
+ /// Returns all base types of the given entity type, including the type itself, bottom to top.
+ ///
+ /// The entity type.
+ /// Base types.
+ public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNull] this IConventionEntityType entityType)
+ => ((IReadOnlyEntityType)entityType).GetAllBaseTypesInclusiveAscending().Cast();
+
///
/// Gets all types in the model that derive from a given entity type.
///
@@ -79,33 +87,16 @@ public static IEnumerable GetDirectlyDerivedTypes([NotNul
=> ((EntityType)entityType).GetDirectlyDerivedTypes();
///
- /// Returns all base types of the given , including the type itself, top to bottom.
+ /// Returns all base types of the given , including the type itself, top to bottom.
///
/// The entity type.
/// Base types.
public static IEnumerable GetAllBaseTypesInclusive([NotNull] this IConventionEntityType entityType)
- => GetAllBaseTypesInclusiveAscending(entityType).Reverse();
-
- ///
- /// Returns all base types of the given , including the type itself, bottom to top.
- ///
- /// The entity type.
- /// Base types.
- public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNull] this IConventionEntityType entityType)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- var tmp = (IConventionEntityType?)entityType;
- while (tmp != null)
- {
- yield return tmp;
- tmp = tmp.BaseType;
- }
- }
+ => entityType.GetAllBaseTypesInclusiveAscending().Reverse().Cast();
///
///
- /// Gets all keys declared on the given .
+ /// Gets all keys declared on the given .
///
///
/// This method does not return keys declared on base types.
@@ -118,6 +109,40 @@ public static IEnumerable GetAllBaseTypesInclusiveAscendi
public static IEnumerable GetDeclaredKeys([NotNull] this IConventionEntityType entityType)
=> ((EntityType)entityType).GetDeclaredKeys();
+ ///
+ /// Gets the primary or alternate key that is defined on the given property. Returns if no key is defined
+ /// for the given property.
+ ///
+ /// The entity type.
+ /// The property that the key is defined on.
+ /// The key, or null if none is defined.
+ public static IConventionKey? FindKey([NotNull] this IConventionEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindKey(new[] { property });
+
+ ///
+ /// Adds a new alternate key to this entity type.
+ ///
+ /// The entity type.
+ /// The property to use as an alternate key.
+ /// Indicates whether the configuration was specified using a data annotation.
+ /// The newly created key.
+ public static IConventionKey? AddKey(
+ [NotNull] this IConventionEntityType entityType,
+ [NotNull] IConventionProperty property,
+ bool fromDataAnnotation = false)
+ => Check.NotNull(entityType, nameof(entityType)).AddKey(new[] { property }, fromDataAnnotation);
+
+ ///
+ /// Removes a primary or alternate key from this entity type.
+ ///
+ /// The entity type.
+ /// The properties that make up the key.
+ /// The key that was removed.
+ public static IConventionKey? RemoveKey(
+ [NotNull] this IConventionEntityType entityType,
+ [NotNull] IReadOnlyList properties)
+ => ((EntityType)entityType).RemoveKey(properties);
+
///
///
/// Gets all non-navigation properties declared on the given .
@@ -133,6 +158,15 @@ public static IEnumerable GetDeclaredKeys([NotNull] this IConven
public static IEnumerable GetDeclaredProperties([NotNull] this IConventionEntityType entityType)
=> ((EntityType)entityType).GetDeclaredProperties();
+ ///
+ /// Removes a property from this entity type.
+ ///
+ /// The entity type.
+ /// The name of the property to remove.
+ /// The property that was removed.
+ public static IConventionProperty? RemoveProperty([NotNull] this IConventionEntityType entityType, [NotNull] string name)
+ => ((EntityType)entityType).RemoveProperty(name);
+
///
///
/// Gets all navigation properties declared on the given .
@@ -170,7 +204,7 @@ public static IEnumerable GetDeclaredServiceProperti
///
/// This method does not return indexes declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same index more than once.
- /// Use to also return indexes declared on base types.
+ /// Use to also return indexes declared on base types.
///
///
/// The entity type.
@@ -179,51 +213,52 @@ public static IEnumerable GetDeclaredIndexes([NotNull] this IC
=> ((EntityType)entityType).GetDeclaredIndexes();
///
- /// Removes a property from this entity type.
+ ///
+ /// Gets all indexes declared on the types derived from the given .
+ ///
///
/// The entity type.
- /// The name of the property to remove.
- /// The property that was removed.
- public static IConventionProperty? RemoveProperty([NotNull] this IConventionEntityType entityType, [NotNull] string name)
- => ((EntityType)entityType).RemoveProperty(name);
+ /// Derived indexes.
+ public static IEnumerable GetDerivedIndexes([NotNull] this IConventionEntityType entityType)
+ => ((EntityType)entityType).GetDerivedIndexes();
///
- /// Gets the primary or alternate key that is defined on the given property. Returns if no key is defined
- /// for the given property.
+ ///
+ /// Gets the unnamed index defined on the given property. Returns if no such index is defined.
+ ///
+ ///
+ /// Named indexes will not be returned even if the list of properties matches.
+ ///
///
/// The entity type.
- /// The property that the key is defined on.
- /// The key, or null if none is defined.
- public static IConventionKey? FindKey([NotNull] this IConventionEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindKey(new[] { property });
- }
+ /// The property to find the index on.
+ /// The index, or null if none is found.
+ public static IConventionIndex? FindIndex([NotNull] this IConventionEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindIndex(new[] { property });
///
- /// Adds a new alternate key to this entity type.
+ /// Adds an index to this entity type.
///
/// The entity type.
- /// The property to use as an alternate key.
+ /// The property to be indexed.
/// Indicates whether the configuration was specified using a data annotation.
- /// The newly created key.
- public static IConventionKey? AddKey(
+ /// The newly created index.
+ public static IConventionIndex? AddIndex(
[NotNull] this IConventionEntityType entityType,
[NotNull] IConventionProperty property,
bool fromDataAnnotation = false)
- => Check.NotNull(entityType, nameof(entityType)).AddKey(new[] { property }, fromDataAnnotation);
+ => Check.NotNull(entityType, nameof(entityType)).AddIndex(new[] { property }, fromDataAnnotation);
///
- /// Removes a primary or alternate key from this entity type.
+ /// Removes an index from this entity type.
///
/// The entity type.
- /// The properties that make up the key.
- /// The key that was removed.
- public static IConventionKey? RemoveKey(
+ /// The properties that make up the index.
+ /// The index that was removed.
+ public static IConventionIndex? RemoveIndex(
[NotNull] this IConventionEntityType entityType,
[NotNull] IReadOnlyList properties)
- => ((EntityType)entityType).RemoveKey(properties);
+ => ((EntityType)entityType).RemoveIndex(properties);
///
///
@@ -244,11 +279,6 @@ public static IEnumerable GetDeclaredForeignKeys([NotNull
///
/// Gets all foreign keys declared on the types derived from the given .
///
- ///
- /// This method does not return foreign keys declared on the given entity type itself.
- /// Use to return foreign keys declared on this
- /// and base entity typed types.
- ///
///
/// The entity type.
/// Derived foreign keys.
@@ -264,7 +294,7 @@ public static IEnumerable GetDerivedForeignKeys([NotNull]
/// The foreign keys.
public static IEnumerable FindForeignKeys(
[NotNull] this IConventionEntityType entityType,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
=> entityType.FindForeignKeys(new[] { property });
///
@@ -276,7 +306,7 @@ public static IEnumerable FindForeignKeys(
/// The foreign keys.
public static IEnumerable FindForeignKeys(
[NotNull] this IConventionEntityType entityType,
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> ((EntityType)entityType).FindForeignKeys(properties);
///
@@ -294,14 +324,10 @@ public static IEnumerable FindForeignKeys(
/// The foreign key, or if none is defined.
public static IConventionForeignKey? FindForeignKey(
[NotNull] this IConventionEntityType entityType,
- [NotNull] IProperty property,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindForeignKey(new[] { property }, principalKey, principalEntityType);
- }
+ [NotNull] IReadOnlyProperty property,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
+ => entityType.FindForeignKey(new[] { property }, principalKey, principalEntityType);
///
/// Gets the foreign keys declared on the given using the given properties.
@@ -311,7 +337,7 @@ public static IEnumerable FindForeignKeys(
/// Declared foreign keys.
public static IEnumerable FindDeclaredForeignKeys(
[NotNull] this IConventionEntityType entityType,
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> ((EntityType)entityType).FindDeclaredForeignKeys(properties);
///
@@ -338,7 +364,7 @@ public static IEnumerable GetDeclaredReferencingForeignKe
/// The entity type.
/// The relationship to the owner if this is an owned type or otherwise.
public static IConventionForeignKey? FindOwnership([NotNull] this IConventionEntityType entityType)
- => ((EntityType)entityType).FindOwnership();
+ => (IConventionForeignKey?)((IReadOnlyEntityType)entityType).FindOwnership();
///
/// Adds a new relationship to this entity type.
@@ -400,7 +426,7 @@ public static IEnumerable GetDeclaredReferencingForeignKe
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
public static IConventionNavigation? FindNavigation([NotNull] this IConventionEntityType entityType, [NotNull] string name)
- => ((EntityType)entityType).FindNavigation(name);
+ => (IConventionNavigation?)((IReadOnlyEntityType)entityType).FindNavigation(name);
///
/// Gets a navigation property on the given entity type. Does not return navigation properties defined on a base type.
@@ -419,7 +445,7 @@ public static IEnumerable GetDeclaredReferencingForeignKe
/// The defining navigation if one exists or otherwise.
[Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
public static IConventionNavigation? FindDefiningNavigation([NotNull] this IConventionEntityType entityType)
- => (IConventionNavigation?)((IEntityType)entityType).FindDefiningNavigation();
+ => (IConventionNavigation?)((IReadOnlyEntityType)entityType).FindDefiningNavigation();
///
/// Gets all navigation properties on the given entity type.
@@ -427,7 +453,7 @@ public static IEnumerable GetDeclaredReferencingForeignKe
/// The entity type.
/// All navigation properties on the given entity type.
public static IEnumerable GetNavigations([NotNull] this IConventionEntityType entityType)
- => ((EntityType)entityType).GetNavigations();
+ => ((IReadOnlyEntityType)entityType).GetNavigations().Cast();
///
///
@@ -442,14 +468,7 @@ public static IEnumerable GetNavigations([NotNull] this I
/// The property on the entity class.
/// The property, or if none is found.
public static IConventionProperty? FindProperty([NotNull] this IConventionEntityType entityType, [NotNull] MemberInfo memberInfo)
- {
- Check.NotNull(entityType, nameof(entityType));
- Check.NotNull(memberInfo, nameof(memberInfo));
-
- return (memberInfo as PropertyInfo)?.IsIndexerProperty() == true
- ? null
- : entityType.FindProperty(memberInfo.GetSimpleMemberName());
- }
+ => (IConventionProperty?)((IReadOnlyEntityType)entityType).FindProperty(memberInfo);
///
///
@@ -465,7 +484,24 @@ public static IEnumerable GetNavigations([NotNull] this I
public static IReadOnlyList? FindProperties(
[NotNull] this IConventionEntityType entityType,
[NotNull] IReadOnlyList propertyNames)
- => ((EntityType)entityType).FindProperties(Check.NotNull(propertyNames, nameof(propertyNames)));
+ => (IReadOnlyList?)((IReadOnlyEntityType)entityType).FindProperties(propertyNames);
+
+ ///
+ ///
+ /// Gets a property with the given name.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties. Use
+ /// to find a navigation property.
+ ///
+ ///
+ /// The entity type.
+ /// The property name.
+ /// The property, or if none is found.
+ public static IConventionProperty GetProperty(
+ [NotNull] this IConventionEntityType entityType,
+ [NotNull] string name)
+ => (IConventionProperty)((IReadOnlyEntityType)entityType).GetProperty(name);
///
/// Finds a property declared on the type with the given name.
@@ -557,48 +593,6 @@ public static IEnumerable GetNavigations([NotNull] this I
return entityType.AddProperty(name, propertyType, indexerPropertyInfo, setTypeConfigurationSource, fromDataAnnotation);
}
- ///
- ///
- /// Gets the unnamed index defined on the given property. Returns if no such index is defined.
- ///
- ///
- /// Named indexes will not be returned even if the list of properties matches.
- ///
- ///
- /// The entity type.
- /// The property to find the index on.
- /// The index, or null if none is found.
- public static IConventionIndex? FindIndex([NotNull] this IConventionEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindIndex(new[] { property });
- }
-
- ///
- /// Adds an index to this entity type.
- ///
- /// The entity type.
- /// The property to be indexed.
- /// Indicates whether the configuration was specified using a data annotation.
- /// The newly created index.
- public static IConventionIndex? AddIndex(
- [NotNull] this IConventionEntityType entityType,
- [NotNull] IConventionProperty property,
- bool fromDataAnnotation = false)
- => Check.NotNull(entityType, nameof(entityType)).AddIndex(new[] { property }, fromDataAnnotation);
-
- ///
- /// Removes an index from this entity type.
- ///
- /// The entity type.
- /// The properties that make up the index.
- /// The index that was removed.
- public static IConventionIndex? RemoveIndex(
- [NotNull] this IConventionEntityType entityType,
- [NotNull] IReadOnlyList properties)
- => ((EntityType)entityType).RemoveIndex(properties);
-
///
/// Sets the change tracking strategy to use for this entity type. This strategy indicates how the
/// context detects changes to properties for an instance of the entity type.
@@ -678,10 +672,10 @@ public static void SetDefiningQuery(
///
/// The entity type.
public static IConventionProperty? GetDiscriminatorProperty([NotNull] this IConventionEntityType entityType)
- => (IConventionProperty?)((IEntityType)entityType).GetDiscriminatorProperty();
+ => (IConventionProperty?)((IReadOnlyEntityType)entityType).GetDiscriminatorProperty();
///
- /// Sets the that will be used for storing a discriminator value.
+ /// Sets the that will be used for storing a discriminator value.
///
/// The entity type.
/// The property to set.
@@ -689,7 +683,7 @@ public static void SetDefiningQuery(
/// The discriminator property.
public static IConventionProperty? SetDiscriminatorProperty(
[NotNull] this IConventionEntityType entityType,
- [CanBeNull] IProperty? property,
+ [CanBeNull] IReadOnlyProperty? property,
bool fromDataAnnotation = false)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType()
.SetDiscriminatorProperty(
diff --git a/src/EFCore/Extensions/ConventionForeignKeyExtensions.cs b/src/EFCore/Extensions/ConventionForeignKeyExtensions.cs
index cbcf3c640a1..77f6a4fed00 100644
--- a/src/EFCore/Extensions/ConventionForeignKeyExtensions.cs
+++ b/src/EFCore/Extensions/ConventionForeignKeyExtensions.cs
@@ -23,7 +23,7 @@ public static class ConventionForeignKeyExtensions
public static IConventionEntityType GetRelatedEntityType(
[NotNull] this IConventionForeignKey foreignKey,
[NotNull] IConventionEntityType entityType)
- => (IConventionEntityType)((IForeignKey)foreignKey).GetRelatedEntityType(entityType);
+ => (IConventionEntityType)((IReadOnlyForeignKey)foreignKey).GetRelatedEntityType(entityType);
///
/// Returns a navigation associated with this foreign key.
diff --git a/src/EFCore/Extensions/ConventionKeyExtensions.cs b/src/EFCore/Extensions/ConventionKeyExtensions.cs
index d887236d4cf..30451df0a5f 100644
--- a/src/EFCore/Extensions/ConventionKeyExtensions.cs
+++ b/src/EFCore/Extensions/ConventionKeyExtensions.cs
@@ -22,6 +22,6 @@ public static class ConventionKeyExtensions
/// The key to find the foreign keys for.
/// The foreign keys that reference the given key.
public static IEnumerable GetReferencingForeignKeys([NotNull] this IConventionKey key)
- => ((IKey)key).GetReferencingForeignKeys().Cast();
+ => ((IReadOnlyKey)key).GetReferencingForeignKeys().Cast();
}
}
diff --git a/src/EFCore/Extensions/ConventionModelExtensions.cs b/src/EFCore/Extensions/ConventionModelExtensions.cs
index b407774a7de..9a0196ed6f6 100644
--- a/src/EFCore/Extensions/ConventionModelExtensions.cs
+++ b/src/EFCore/Extensions/ConventionModelExtensions.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
@@ -24,7 +25,7 @@ public static class ConventionModelExtensions
///
/// The model to find the entity type in.
/// The type to find the corresponding entity type for.
- /// The entity type, or if none if found.
+ /// The entity type, or if none is found.
public static IConventionEntityType? FindEntityType([NotNull] this IConventionModel model, [NotNull] Type type)
=> ((Model)model).FindEntityType(type);
@@ -36,13 +37,13 @@ public static class ConventionModelExtensions
/// The type of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
public static IConventionEntityType? FindEntityType(
[NotNull] this IConventionModel model,
[NotNull] Type type,
[NotNull] string definingNavigationName,
[NotNull] IConventionEntityType definingEntityType)
- => (IConventionEntityType?)((IModel)model).FindEntityType(type, definingNavigationName, definingEntityType);
+ => (IConventionEntityType?)((IReadOnlyModel)model).FindEntityType(type, definingNavigationName, definingEntityType);
///
/// Gets the entity types matching the given type.
@@ -146,12 +147,12 @@ public static IReadOnlyCollection GetEntityTypes(
/// The base type.
/// An optional condition for filtering entity types.
/// List of entity types corresponding to the least derived types from the given.
- public static IReadOnlyList FindLeastDerivedEntityTypes(
+ public static IEnumerable FindLeastDerivedEntityTypes(
[NotNull] this IConventionModel model,
[NotNull] Type type,
[CanBeNull] Func? condition = null)
- => Check.NotNull((Model)model, nameof(model))
- .FindLeastDerivedEntityTypes(type, condition);
+ => ((IReadOnlyModel)model).FindLeastDerivedEntityTypes(type, condition == null ? null : t => condition((IConventionEntityType)t))
+ .Cast();
///
///
@@ -324,7 +325,7 @@ public static void AddShared([NotNull] this IConventionModel model, [NotNull] Ty
/// explicitly in cases where the automatic execution is not possible.
///
/// The model to finalize.
- /// The finalized .
+ /// The finalized model.
public static IModel FinalizeModel([NotNull] this IConventionModel model)
=> ((Model)model).FinalizeModel();
}
diff --git a/src/EFCore/Extensions/ConventionPropertyBaseExtensions.cs b/src/EFCore/Extensions/ConventionPropertyBaseExtensions.cs
index 6f17a629af2..1427994511c 100644
--- a/src/EFCore/Extensions/ConventionPropertyBaseExtensions.cs
+++ b/src/EFCore/Extensions/ConventionPropertyBaseExtensions.cs
@@ -32,10 +32,10 @@ public static class ConventionPropertyBaseExtensions
propertyAccessMode, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
/// The property to find configuration source for.
- /// The configuration source for .
+ /// The configuration source for .
public static ConfigurationSource? GetPropertyAccessModeConfigurationSource([NotNull] this IConventionPropertyBase property)
=> property.FindAnnotation(CoreAnnotationNames.PropertyAccessMode)?.GetConfigurationSource();
}
diff --git a/src/EFCore/Extensions/ConventionPropertyExtensions.cs b/src/EFCore/Extensions/ConventionPropertyExtensions.cs
index 1e0d4c47892..de7b89267a0 100644
--- a/src/EFCore/Extensions/ConventionPropertyExtensions.cs
+++ b/src/EFCore/Extensions/ConventionPropertyExtensions.cs
@@ -29,7 +29,7 @@ public static class ConventionPropertyExtensions
/// The foreign key property.
/// The first associated principal property, or if none exists.
public static IConventionProperty? FindFirstPrincipal([NotNull] this IConventionProperty property)
- => (IConventionProperty?)((IProperty)property).FindFirstPrincipal();
+ => (IConventionProperty?)((IReadOnlyProperty)property).FindFirstPrincipal();
///
/// Finds the list of principal properties including the given property that the given property is constrained by
@@ -38,7 +38,7 @@ public static class ConventionPropertyExtensions
/// The foreign key property.
/// The list of all associated principal properties including the given property.
public static IReadOnlyList FindPrincipals([NotNull] this IConventionProperty property)
- => ((IProperty)property).FindPrincipals().Cast().ToList();
+ => ((IReadOnlyProperty)property).FindPrincipals().Cast().ToList();
///
/// Gets all foreign keys that use this property (including composite foreign keys in which this property
@@ -49,7 +49,7 @@ public static IReadOnlyList FindPrincipals([NotNull] this I
/// The foreign keys that use this property.
///
public static IEnumerable GetContainingForeignKeys([NotNull] this IConventionProperty property)
- => ((IProperty)property).GetContainingForeignKeys().Cast();
+ => ((IReadOnlyProperty)property).GetContainingForeignKeys().Cast();
///
/// Gets all indexes that use this property (including composite indexes in which this property
@@ -71,7 +71,7 @@ public static IEnumerable GetContainingIndexes([NotNull] this
/// The primary that use this property, or if it is not part of the primary key.
///
public static IConventionKey? FindContainingPrimaryKey([NotNull] this IConventionProperty property)
- => (IConventionKey?)((IProperty)property).FindContainingPrimaryKey();
+ => (IConventionKey?)((IReadOnlyProperty)property).FindContainingPrimaryKey();
///
/// Gets all primary or alternate keys that use this property (including composite keys in which this property
@@ -98,10 +98,10 @@ public static IEnumerable GetContainingKeys([NotNull] this IConv
typeMapping, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- /// Gets the for .
+ /// Gets the for of the property.
///
/// The property.
- /// The for .
+ /// The for of the property.
public static ConfigurationSource? GetTypeMappingConfigurationSource([NotNull] this IConventionProperty property)
=> ((Property)property).GetTypeMappingConfigurationSource();
diff --git a/src/EFCore/Extensions/EntityTypeExtensions.cs b/src/EFCore/Extensions/EntityTypeExtensions.cs
index d63174ae5a0..1b67e8db378 100644
--- a/src/EFCore/Extensions/EntityTypeExtensions.cs
+++ b/src/EFCore/Extensions/EntityTypeExtensions.cs
@@ -22,17 +22,17 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Entity type extension methods for .
///
public static class EntityTypeExtensions
{
///
- /// Returns all the derived types of the given , including the type itself,
+ /// Returns all the derived types of the given , including the type itself,
/// which are not .
///
/// The entity type.
/// Non-abstract, derived types.
- public static IEnumerable GetConcreteDerivedTypesInclusive([NotNull] this IEntityType entityType)
+ public static IEnumerable GetConcreteDerivedTypesInclusive([NotNull] this IReadOnlyEntityType entityType)
=> entityType.GetDerivedTypesInclusive().Where(et => !et.IsAbstract());
///
@@ -41,7 +41,7 @@ public static IEnumerable GetConcreteDerivedTypesInclusive([NotNull
/// The entity type.
/// if the type is abstract, otherwise.
[DebuggerStepThrough]
- public static bool IsAbstract([NotNull] this ITypeBase type)
+ public static bool IsAbstract([NotNull] this IReadOnlyTypeBase type)
=> type.ClrType.IsAbstract;
///
@@ -51,7 +51,7 @@ public static bool IsAbstract([NotNull] this ITypeBase type)
///
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
///
- public static IEntityType GetRootType([NotNull] this IEntityType entityType)
+ public static IReadOnlyEntityType GetRootType([NotNull] this IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
@@ -65,7 +65,7 @@ public static IEntityType GetRootType([NotNull] this IEntityType entityType)
///
/// The base types.
///
- public static IEnumerable GetAllBaseTypes([NotNull] this IEntityType entityType)
+ public static IEnumerable GetAllBaseTypes([NotNull] this IReadOnlyEntityType entityType)
=> entityType.GetAllBaseTypesAscending().Reverse();
///
@@ -75,7 +75,7 @@ public static IEnumerable GetAllBaseTypes([NotNull] this IEntityTyp
///
/// The base types.
///
- public static IEnumerable GetAllBaseTypesAscending([NotNull] this IEntityType entityType)
+ public static IEnumerable GetAllBaseTypesAscending([NotNull] this IReadOnlyEntityType entityType)
=> entityType.GetAllBaseTypesInclusiveAscending().Skip(1);
///
@@ -83,15 +83,15 @@ public static IEnumerable GetAllBaseTypesAscending([NotNull] this I
///
/// The entity type.
/// The derived types.
- public static IEnumerable GetDerivedTypes([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDerivedTypes([NotNull] this IReadOnlyEntityType entityType)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType().GetDerivedTypes();
///
- /// Returns all derived types of the given , including the type itself.
+ /// Returns all derived types of the given , including the type itself.
///
/// The entity type.
/// Derived types.
- public static IEnumerable GetDerivedTypesInclusive([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDerivedTypesInclusive([NotNull] this IReadOnlyEntityType entityType)
=> new[] { entityType }.Concat(entityType.GetDerivedTypes());
///
@@ -99,7 +99,7 @@ public static IEnumerable GetDerivedTypesInclusive([NotNull] this I
///
/// The entity type.
/// The derived types.
- public static IEnumerable GetDirectlyDerivedTypes([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDirectlyDerivedTypes([NotNull] this IReadOnlyEntityType entityType)
=> ((EntityType)entityType).GetDirectlyDerivedTypes();
///
@@ -111,7 +111,7 @@ public static IEnumerable GetDirectlyDerivedTypes([NotNull] this IE
/// if derives from (or is the same as) ,
/// otherwise .
///
- public static bool IsAssignableFrom([NotNull] this IEntityType entityType, [NotNull] IEntityType derivedType)
+ public static bool IsAssignableFrom([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyEntityType derivedType)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(derivedType, nameof(derivedType));
@@ -140,7 +140,7 @@ public static bool IsAssignableFrom([NotNull] this IEntityType entityType, [NotN
/// The closest common parent of and ,
/// or null if they have not common parent.
///
- public static IEntityType? GetClosestCommonParent([NotNull] this IEntityType entityType1, [NotNull] IEntityType entityType2)
+ public static IReadOnlyEntityType? GetClosestCommonParent([NotNull] this IReadOnlyEntityType entityType1, [NotNull] IReadOnlyEntityType entityType2)
{
Check.NotNull(entityType1, nameof(entityType1));
Check.NotNull(entityType2, nameof(entityType2));
@@ -159,7 +159,7 @@ public static bool IsAssignableFrom([NotNull] this IEntityType entityType, [NotN
/// if derives from (but is not the same as) ,
/// otherwise .
///
- public static bool IsStrictlyDerivedFrom([NotNull] this IEntityType entityType, [NotNull] IEntityType baseType)
+ public static bool IsStrictlyDerivedFrom([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyEntityType baseType)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(baseType, nameof(baseType));
@@ -176,7 +176,7 @@ public static bool IsStrictlyDerivedFrom([NotNull] this IEntityType entityType,
/// The least derived type between the specified two.
/// If the given entity types are not related, then is returned.
///
- public static IEntityType? LeastDerivedType([NotNull] this IEntityType entityType, [NotNull] IEntityType otherEntityType)
+ public static IReadOnlyEntityType? LeastDerivedType([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyEntityType otherEntityType)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(otherEntityType, nameof(otherEntityType));
@@ -189,23 +189,23 @@ public static bool IsStrictlyDerivedFrom([NotNull] this IEntityType entityType,
}
///
- /// Returns all base types of the given , including the type itself, top to bottom.
+ /// Returns all base types of the given , including the type itself, top to bottom.
///
/// The entity type.
/// Base types.
- public static IEnumerable GetAllBaseTypesInclusive([NotNull] this IEntityType entityType)
+ public static IEnumerable GetAllBaseTypesInclusive([NotNull] this IReadOnlyEntityType entityType)
=> GetAllBaseTypesInclusiveAscending(entityType).Reverse();
///
- /// Returns all base types of the given , including the type itself, bottom to top.
+ /// Returns all base types of the given , including the type itself, bottom to top.
///
/// The entity type.
/// Base types.
- public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNull] this IEntityType entityType)
+ public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNull] this IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
- var tmp = (IEntityType?)entityType;
+ var tmp = (IReadOnlyEntityType?)entityType;
while (tmp != null)
{
yield return tmp;
@@ -215,52 +215,52 @@ public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNul
///
///
- /// Gets all keys declared on the given .
+ /// Gets all keys declared on the given .
///
///
/// This method does not return keys declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same key more than once.
- /// Use to also return keys declared on base types.
+ /// Use to also return keys declared on base types.
///
///
/// The entity type.
/// Declared keys.
- public static IEnumerable GetDeclaredKeys([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDeclaredKeys([NotNull] this IReadOnlyEntityType entityType)
=> entityType.AsEntityType().GetDeclaredKeys();
///
///
- /// Gets all foreign keys declared on the given .
+ /// Gets all foreign keys declared on the given .
///
///
/// This method does not return foreign keys declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same foreign key more than once.
- /// Use to also return foreign keys declared on base types.
+ /// Use to also return foreign keys declared on base types.
///
///
/// The entity type.
/// Declared foreign keys.
- public static IEnumerable GetDeclaredForeignKeys([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDeclaredForeignKeys([NotNull] this IReadOnlyEntityType entityType)
=> entityType.AsEntityType().GetDeclaredForeignKeys();
///
///
- /// Gets all foreign keys declared on the types derived from the given .
+ /// Gets all foreign keys declared on the types derived from the given .
///
///
/// This method does not return foreign keys declared on the given entity type itself.
- /// Use to return foreign keys declared on this
+ /// Use to return foreign keys declared on this
/// and base entity typed types.
///
///
/// The entity type.
/// Derived foreign keys.
- public static IEnumerable GetDerivedForeignKeys([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDerivedForeignKeys([NotNull] this IReadOnlyEntityType entityType)
=> entityType.AsEntityType().GetDerivedForeignKeys();
///
///
- /// Gets all navigation properties declared on the given .
+ /// Gets all navigation properties declared on the given .
///
///
/// This method does not return navigation properties declared on base types.
@@ -270,65 +270,85 @@ public static IEnumerable GetDerivedForeignKeys([NotNull] this IEnt
///
/// The entity type.
/// Declared navigation properties.
- public static IEnumerable GetDeclaredNavigations([NotNull] this IEntityType entityType)
- => entityType.GetDeclaredForeignKeys()
- .Concat(entityType.GetDeclaredReferencingForeignKeys())
- .SelectMany(foreignKey => foreignKey.FindNavigationsFrom(entityType))
- .Distinct()
- .OrderBy(m => m.Name);
+ public static IEnumerable GetDeclaredNavigations([NotNull] this IReadOnlyEntityType entityType)
+ => ((EntityType)entityType).GetDeclaredNavigations();
///
///
- /// Gets all non-navigation properties declared on the given .
+ /// Gets all non-navigation properties declared on the given .
///
///
/// This method does not return properties declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same property more than once.
- /// Use to also return properties declared on base types.
+ /// Use to also return properties declared on base types.
///
///
/// The entity type.
/// Declared non-navigation properties.
- public static IEnumerable GetDeclaredProperties([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDeclaredProperties([NotNull] this IReadOnlyEntityType entityType)
=> entityType.AsEntityType().GetDeclaredProperties();
///
///
- /// Gets all service properties declared on the given .
+ /// Gets all service properties declared on the given .
///
///
/// This method does not return properties declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same property more than once.
- /// Use to also return properties declared on base types.
+ /// Use to also return properties declared on base types.
///
///
/// The entity type.
/// Declared service properties.
- public static IEnumerable GetDeclaredServiceProperties([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDeclaredServiceProperties([NotNull] this IReadOnlyEntityType entityType)
=> entityType.AsEntityType().GetDeclaredServiceProperties();
///
///
- /// Gets all indexes declared on the given .
+ /// Gets all indexes declared on the given .
///
///
/// This method does not return indexes declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same index more than once.
- /// Use to also return indexes declared on base types.
+ /// Use to also return indexes declared on base types.
///
///
/// The entity type.
/// Declared indexes.
- public static IEnumerable GetDeclaredIndexes([NotNull] this IEntityType entityType)
- => entityType.AsEntityType().GetDeclaredIndexes();
+ public static IEnumerable GetDeclaredIndexes([NotNull] this IReadOnlyEntityType entityType)
+ => ((EntityType)entityType).GetDeclaredIndexes();
///
- /// Gets the friendly display name for the given .
+ ///
+ /// Gets all indexes declared on the types derived from the given .
+ ///
+ ///
+ /// The entity type.
+ /// Derived indexes.
+ public static IEnumerable GetDerivedIndexes([NotNull] this IReadOnlyEntityType entityType)
+ => ((EntityType)entityType).GetDerivedIndexes();
+
+ ///
+ ///
+ /// Gets the unnamed index defined on the given property. Returns if no such index is defined.
+ ///
+ ///
+ /// Named indexes will not be returned even if the list of properties matches.
+ ///
+ ///
+ /// The entity type.
+ /// The property to find the index on.
+ /// The index, or null if none is found.
+ public static IReadOnlyIndex? FindIndex([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindIndex(new[] { property });
+
+ ///
+ /// Gets the friendly display name for the given .
///
/// The entity type.
/// The display name.
[DebuggerStepThrough]
- public static string DisplayName([NotNull] this ITypeBase type)
+ public static string DisplayName([NotNull] this IReadOnlyTypeBase type)
{
if (!type.HasSharedClrType)
{
@@ -367,20 +387,20 @@ public static string DisplayName([NotNull] this ITypeBase type)
}
///
- /// Gets the unique name for the given .
+ /// Gets the unique name for the given .
///
/// The entity type.
/// The full name.
[DebuggerStepThrough]
- public static string FullName([NotNull] this ITypeBase type) => type.Name;
+ public static string FullName([NotNull] this IReadOnlyTypeBase type) => type.Name;
///
- /// Gets a short name for the given that can be used in other identifiers.
+ /// Gets a short name for the given that can be used in other identifiers.
///
/// The entity type.
/// The short name.
[DebuggerStepThrough]
- public static string ShortName([NotNull] this ITypeBase type)
+ public static string ShortName([NotNull] this IReadOnlyTypeBase type)
{
if (!type.HasSharedClrType)
{
@@ -412,7 +432,7 @@ public static string ShortName([NotNull] this ITypeBase type)
/// if this entity type has a defining navigation.
[DebuggerStepThrough]
[Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
- public static bool HasDefiningNavigation([NotNull] this IEntityType entityType)
+ public static bool HasDefiningNavigation([NotNull] this IReadOnlyEntityType entityType)
=> entityType.HasDefiningNavigation();
///
@@ -421,7 +441,7 @@ public static bool HasDefiningNavigation([NotNull] this IEntityType entityType)
/// The entity type.
/// if this entity type is owned by another entity type.
[DebuggerStepThrough]
- public static bool IsOwned([NotNull] this IEntityType entityType)
+ public static bool IsOwned([NotNull] this IReadOnlyEntityType entityType)
=> entityType.GetForeignKeys().Any(fk => fk.IsOwnership);
///
@@ -433,7 +453,7 @@ public static bool IsOwned([NotNull] this IEntityType entityType)
/// if is in ownership path of ,
/// otherwise .
///
- public static bool IsInOwnershipPath([NotNull] this IEntityType entityType, [NotNull] IEntityType targetType)
+ public static bool IsInOwnershipPath([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyEntityType targetType)
{
var owner = entityType;
while (true)
@@ -459,12 +479,8 @@ public static bool IsInOwnershipPath([NotNull] this IEntityType entityType, [Not
/// The entity type.
/// The property that the key is defined on.
/// The key, or null if none is defined.
- public static IKey? FindKey([NotNull] this IEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindKey(new[] { property });
- }
+ public static IReadOnlyKey? FindKey([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindKey(new[] { property });
///
/// Gets the foreign keys defined on the given property. Only foreign keys that are defined on exactly the specified
@@ -473,8 +489,8 @@ public static bool IsInOwnershipPath([NotNull] this IEntityType entityType, [Not
/// The entity type.
/// The property to find the foreign keys on.
/// The foreign keys.
- public static IEnumerable FindForeignKeys([NotNull] this IEntityType entityType, [NotNull] IProperty property)
- => property.GetContainingForeignKeys();
+ public static IEnumerable FindForeignKeys([NotNull] this IReadOnlyEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindForeignKeys(new[] { property });
///
/// Gets the foreign keys defined on the given properties. Only foreign keys that are defined on exactly the specified
@@ -483,17 +499,10 @@ public static IEnumerable FindForeignKeys([NotNull] this IEntityTyp
/// The entity type.
/// The properties to find the foreign keys on.
/// The foreign keys.
- public static IEnumerable FindForeignKeys(
- [NotNull] this IEntityType entityType,
- [NotNull] IReadOnlyList properties)
- {
- Check.NotNull(entityType, nameof(entityType));
- Check.NotEmpty(properties, nameof(properties));
- Check.HasNoNulls(properties, nameof(properties));
-
- return entityType.GetForeignKeys()
- .Where(foreignKey => PropertyListComparer.Instance.Equals(foreignKey.Properties, properties));
- }
+ public static IEnumerable FindForeignKeys(
+ [NotNull] this IReadOnlyEntityType entityType,
+ [NotNull] IReadOnlyList properties)
+ => ((EntityType)entityType).FindForeignKeys(properties);
///
/// Gets the foreign key for the given properties that points to a given primary or alternate key. Returns
@@ -508,11 +517,11 @@ public static IEnumerable FindForeignKeys(
/// base type of the hierarchy).
///
/// The foreign key, or if none is defined.
- public static IForeignKey? FindForeignKey(
- [NotNull] this IEntityType entityType,
- [NotNull] IProperty property,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ public static IReadOnlyForeignKey? FindForeignKey(
+ [NotNull] this IReadOnlyEntityType entityType,
+ [NotNull] IReadOnlyProperty property,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
=> Check.NotNull(entityType, nameof(entityType))
.FindForeignKey(
new[] { property }, principalKey, principalEntityType);
@@ -523,7 +532,7 @@ public static IEnumerable FindForeignKeys(
///
/// The entity type.
/// The foreign keys that reference the given entity type.
- public static IEnumerable GetReferencingForeignKeys([NotNull] this IEntityType entityType)
+ public static IEnumerable GetReferencingForeignKeys([NotNull] this IReadOnlyEntityType entityType)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType().GetReferencingForeignKeys();
///
@@ -532,7 +541,7 @@ public static IEnumerable GetReferencingForeignKeys([NotNull] this
///
/// The entity type.
/// The foreign keys that reference the given entity type.
- public static IEnumerable GetDeclaredReferencingForeignKeys([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNull] this IReadOnlyEntityType entityType)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType().GetDeclaredReferencingForeignKeys();
///
@@ -540,8 +549,18 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
///
/// The entity type.
/// The relationship to the owner if this is an owned type or otherwise.
- public static IForeignKey? FindOwnership([NotNull] this IEntityType entityType)
- => ((EntityType)entityType).FindOwnership();
+ public static IReadOnlyForeignKey? FindOwnership([NotNull] this IReadOnlyEntityType entityType)
+ {
+ foreach (var foreignKey in entityType.GetForeignKeys())
+ {
+ if (foreignKey.IsOwnership)
+ {
+ return foreignKey;
+ }
+ }
+
+ return null;
+ }
///
/// Gets a navigation property on the given entity type. Returns if no navigation property is found.
@@ -549,13 +568,8 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
/// The entity type.
/// The navigation property on the entity class.
/// The navigation property, or if none is found.
- public static INavigation? FindNavigation([NotNull] this IEntityType entityType, [NotNull] MemberInfo memberInfo)
- {
- Check.NotNull(entityType, nameof(entityType));
- Check.NotNull(memberInfo, nameof(memberInfo));
-
- return entityType.FindNavigation(memberInfo.GetSimpleMemberName());
- }
+ public static IReadOnlyNavigation? FindNavigation([NotNull] this IReadOnlyEntityType entityType, [NotNull] MemberInfo memberInfo)
+ => entityType.FindNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
///
/// Gets a navigation property on the given entity type. Returns if no navigation property is found.
@@ -563,8 +577,8 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
/// The entity type.
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
- public static INavigation? FindNavigation([NotNull] this IEntityType entityType, [NotNull] string name)
- => Check.NotNull(entityType, nameof(entityType)).AsEntityType().FindNavigation(Check.NotNull(name, nameof(name)));
+ public static IReadOnlyNavigation? FindNavigation([NotNull] this IReadOnlyEntityType entityType, [NotNull] string name)
+ => entityType.FindDeclaredNavigation(Check.NotEmpty(name, nameof(name))) ?? entityType.BaseType?.FindNavigation(name);
///
/// Gets a navigation property on the given entity type. Does not return navigation properties defined on a base type.
@@ -573,8 +587,8 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
/// The entity type.
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
- public static INavigation? FindDeclaredNavigation([NotNull] this IEntityType entityType, [NotNull] string name)
- => Check.NotNull(entityType, nameof(entityType)).AsEntityType().FindDeclaredNavigation(Check.NotNull(name, nameof(name)));
+ public static IReadOnlyNavigation? FindDeclaredNavigation([NotNull] this IReadOnlyEntityType entityType, [NotNull] string name)
+ => ((EntityType)entityType).FindDeclaredNavigation(Check.NotNull(name, nameof(name)));
///
/// Returns the defining navigation if one exists or otherwise.
@@ -582,7 +596,7 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
/// The entity type.
/// The defining navigation if one exists or otherwise.
[Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
- public static INavigation? FindDefiningNavigation([NotNull] this IEntityType entityType)
+ public static IReadOnlyNavigation? FindDefiningNavigation([NotNull] this IReadOnlyEntityType entityType)
{
if (!entityType.HasDefiningNavigation())
{
@@ -598,7 +612,7 @@ public static IEnumerable GetDeclaredReferencingForeignKeys([NotNul
///
/// The entity type.
/// All navigation properties on the given entity type.
- public static IEnumerable GetNavigations([NotNull] this IEntityType entityType)
+ public static IEnumerable GetNavigations([NotNull] this IReadOnlyEntityType entityType)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType().GetNavigations();
///
@@ -607,21 +621,16 @@ public static IEnumerable GetNavigations([NotNull] this IEntityType
///
///
/// This API only finds scalar properties and does not find navigation properties. Use
- /// to find a navigation property.
+ /// to find a navigation property.
///
///
/// The entity type.
/// The member on the entity class.
/// The property, or if none is found.
- public static IProperty? FindProperty([NotNull] this IEntityType entityType, [NotNull] MemberInfo memberInfo)
- {
- Check.NotNull(entityType, nameof(entityType));
- Check.NotNull(memberInfo, nameof(memberInfo));
-
- return (memberInfo as PropertyInfo)?.IsIndexerProperty() == true
+ public static IReadOnlyProperty? FindProperty([NotNull] this IReadOnlyEntityType entityType, [NotNull] MemberInfo memberInfo)
+ => (Check.NotNull(memberInfo, nameof(memberInfo)) as PropertyInfo)?.IsIndexerProperty() == true
? null
: entityType.FindProperty(memberInfo.GetSimpleMemberName());
- }
///
///
@@ -629,13 +638,13 @@ public static IEnumerable GetNavigations([NotNull] this IEntityType
///
///
/// This API only finds scalar properties and does not find navigation properties. Use
- /// to find a navigation property.
+ /// to find a navigation property.
///
///
/// The entity type.
/// The property name.
/// The property, or if none is found.
- public static IProperty GetProperty([NotNull] this IEntityType entityType, [NotNull] string name)
+ public static IReadOnlyProperty GetProperty([NotNull] this IReadOnlyEntityType entityType, [NotNull] string name)
{
Check.NotEmpty(name, nameof(name));
@@ -668,10 +677,10 @@ public static IProperty GetProperty([NotNull] this IEntityType entityType, [NotN
/// The entity type.
/// The property names.
/// The properties, or if any property is not found.
- public static IReadOnlyList? FindProperties(
- [NotNull] this IEntityType entityType,
+ public static IReadOnlyList? FindProperties(
+ [NotNull] this IReadOnlyEntityType entityType,
[NotNull] IReadOnlyList propertyNames)
- => entityType.AsEntityType().FindProperties(Check.NotNull(propertyNames, nameof(propertyNames)));
+ => ((EntityType)entityType).FindProperties(propertyNames);
///
/// Finds a property declared on the type with the given name.
@@ -680,27 +689,9 @@ public static IProperty GetProperty([NotNull] this IEntityType entityType, [NotN
/// The entity type.
/// The property name.
/// The property, or if none is found.
- public static IProperty? FindDeclaredProperty([NotNull] this IEntityType entityType, [NotNull] string name)
+ public static IReadOnlyProperty? FindDeclaredProperty([NotNull] this IReadOnlyEntityType entityType, [NotNull] string name)
=> entityType.AsEntityType().FindDeclaredProperty(name);
- ///
- ///
- /// Gets the unnamed index defined on the given property. Returns if no such index is defined.
- ///
- ///
- /// Named indexes will not be returned even if the list of properties matches.
- ///
- ///
- /// The entity type.
- /// The property to find the index on.
- /// The index, or null if none is found.
- public static IIndex? FindIndex([NotNull] this IEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindIndex(new[] { property });
- }
-
///
/// Gets the change tracking strategy being used for this entity type. This strategy indicates how the
/// context detects changes to properties for an instance of the entity type.
@@ -708,7 +699,7 @@ public static IProperty GetProperty([NotNull] this IEntityType entityType, [NotN
/// The entity type.
/// The change tracking strategy.
[DebuggerStepThrough]
- public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IEntityType entityType)
+ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IReadOnlyEntityType entityType)
=> ((EntityType)entityType).GetChangeTrackingStrategy();
///
@@ -718,7 +709,7 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IE
/// If true, then provider values are used.
/// The data.
public static IEnumerable> GetSeedData(
- [NotNull] this IEntityType entityType,
+ [NotNull] this IReadOnlyEntityType entityType,
bool providerValues = false)
=> entityType.AsEntityType().GetSeedData(providerValues);
@@ -727,7 +718,7 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IE
///
/// The entity type to get the query filter for.
/// The LINQ expression filter.
- public static LambdaExpression? GetQueryFilter([NotNull] this IEntityType entityType)
+ public static LambdaExpression? GetQueryFilter([NotNull] this IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
@@ -740,7 +731,7 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IE
/// The entity type to get the defining query for.
/// The LINQ query used as the default source.
[Obsolete("Use InMemoryEntityTypeExtensions.GetInMemoryQuery")]
- public static LambdaExpression? GetDefiningQuery([NotNull] this IEntityType entityType)
+ public static LambdaExpression? GetDefiningQuery([NotNull] this IReadOnlyEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
@@ -748,10 +739,10 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IE
}
///
- /// Returns the that will be used for storing a discriminator value.
+ /// Returns the that will be used for storing a discriminator value.
///
/// The entity type.
- public static IProperty? GetDiscriminatorProperty([NotNull] this IEntityType entityType)
+ public static IReadOnlyProperty? GetDiscriminatorProperty([NotNull] this IReadOnlyEntityType entityType)
{
if (entityType.BaseType != null)
{
@@ -767,11 +758,11 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IE
/// Returns the value indicating whether the discriminator mapping is complete for this entity type.
///
/// The entity type.
- public static bool GetIsDiscriminatorMappingComplete([NotNull] this IEntityType entityType)
+ public static bool GetIsDiscriminatorMappingComplete([NotNull] this IReadOnlyEntityType entityType)
=> (bool?)entityType[CoreAnnotationNames.DiscriminatorMappingComplete]
?? GetDefaultIsDiscriminatorMappingComplete(entityType);
- private static bool GetDefaultIsDiscriminatorMappingComplete(IEntityType entityType)
+ private static bool GetDefaultIsDiscriminatorMappingComplete(IReadOnlyEntityType entityType)
=> true;
///
@@ -779,7 +770,7 @@ private static bool GetDefaultIsDiscriminatorMappingComplete(IEntityType entityT
///
/// The entity type.
/// The discriminator value for this entity type.
- public static object? GetDiscriminatorValue([NotNull] this IEntityType entityType)
+ public static object? GetDiscriminatorValue([NotNull] this IReadOnlyEntityType entityType)
=> entityType[CoreAnnotationNames.DiscriminatorValue];
///
@@ -796,7 +787,7 @@ private static bool GetDefaultIsDiscriminatorMappingComplete(IEntityType entityT
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IEntityType entityType,
+ [NotNull] this IReadOnlyEntityType entityType,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/ForeignKeyExtensions.cs b/src/EFCore/Extensions/ForeignKeyExtensions.cs
index 24191b2d294..2b3d91cb798 100644
--- a/src/EFCore/Extensions/ForeignKeyExtensions.cs
+++ b/src/EFCore/Extensions/ForeignKeyExtensions.cs
@@ -17,7 +17,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class ForeignKeyExtensions
{
@@ -31,11 +31,11 @@ public static class ForeignKeyExtensions
/// not used in application code.
///
///
- /// The for which a factory is needed.
+ /// The for which a factory is needed.
/// The type of key instanceas.
/// A new factory.
public static IDependentKeyValueFactory? GetDependentKeyValueFactory(
- [NotNull] this IForeignKey foreignKey)
+ [NotNull] this IReadOnlyForeignKey foreignKey)
=> (IDependentKeyValueFactory?)foreignKey.AsForeignKey().DependentKeyValueFactory;
///
@@ -44,7 +44,8 @@ public static class ForeignKeyExtensions
/// The foreign key.
/// One of the entity types related by the foreign key.
/// The entity type related to the given one.
- public static IEntityType GetRelatedEntityType([NotNull] this IForeignKey foreignKey, [NotNull] IEntityType entityType)
+ public static IReadOnlyEntityType GetRelatedEntityType(
+ [NotNull] this IReadOnlyForeignKey foreignKey, [NotNull] IReadOnlyEntityType entityType)
{
if (foreignKey.DeclaringEntityType != entityType
&& foreignKey.PrincipalEntityType != entityType)
@@ -71,7 +72,7 @@ public static IEntityType GetRelatedEntityType([NotNull] this IForeignKey foreig
///
/// A navigation associated with this foreign key or .
///
- public static INavigation? GetNavigation([NotNull] this IForeignKey foreignKey, bool pointsToPrincipal)
+ public static IReadOnlyNavigation? GetNavigation([NotNull] this IReadOnlyForeignKey foreignKey, bool pointsToPrincipal)
=> pointsToPrincipal ? foreignKey.DependentToPrincipal : foreignKey.PrincipalToDependent;
///
@@ -79,7 +80,7 @@ public static IEntityType GetRelatedEntityType([NotNull] this IForeignKey foreig
///
/// The foreign key.
/// A value indicating whether the foreign key is defined on the primary key and pointing to the same primary key.
- public static bool IsBaseLinking([NotNull] this IForeignKey foreignKey)
+ public static bool IsBaseLinking([NotNull] this IReadOnlyForeignKey foreignKey)
{
var primaryKey = foreignKey.DeclaringEntityType.FindPrimaryKey();
return primaryKey == foreignKey.PrincipalKey
@@ -100,7 +101,7 @@ public static bool IsBaseLinking([NotNull] this IForeignKey foreignKey)
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IForeignKey foreignKey,
+ [NotNull] this IReadOnlyForeignKey foreignKey,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/IndexExtensions.cs b/src/EFCore/Extensions/IndexExtensions.cs
index 4d121c3009e..07cb4af6da6 100644
--- a/src/EFCore/Extensions/IndexExtensions.cs
+++ b/src/EFCore/Extensions/IndexExtensions.cs
@@ -15,7 +15,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class IndexExtensions
{
@@ -31,7 +31,7 @@ public static class IndexExtensions
/// The index metadata.
/// The type of the index instance.
/// The factory.
- public static IDependentKeyValueFactory GetNullableValueFactory([NotNull] this IIndex index)
+ public static IDependentKeyValueFactory GetNullableValueFactory([NotNull] this IReadOnlyIndex index)
=> index.AsIndex().GetNullableValueFactory();
///
@@ -48,7 +48,7 @@ public static IDependentKeyValueFactory GetNullableValueFactory([Not
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IIndex index,
+ [NotNull] this IReadOnlyIndex index,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/Internal/ExpressionExtensions.cs b/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
index 182aa34dc12..69eb251ad8a 100644
--- a/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
+++ b/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
@@ -34,7 +34,7 @@ public static class ExpressionExtensions
///
public static Expression MakeHasDefaultValue(
[NotNull] this Expression currentValueExpression,
- [CanBeNull] IPropertyBase? propertyBase)
+ [CanBeNull] IReadOnlyPropertyBase? propertyBase)
{
if (!currentValueExpression.Type.IsValueType)
{
@@ -52,7 +52,7 @@ public static Expression MakeHasDefaultValue(
currentValueExpression.Type.GetRequiredMethod("get_HasValue")));
}
- var property = propertyBase as IProperty;
+ var property = propertyBase as IReadOnlyProperty;
var clrType = propertyBase?.ClrType ?? currentValueExpression.Type;
var comparer = property?.GetValueComparer()
?? ValueComparer.CreateDefault(clrType, favorStructuralComparisons: false);
@@ -219,7 +219,7 @@ private static readonly MethodInfo _objectEqualsMethodInfo
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static Expression BuildPredicate(
- [NotNull] IReadOnlyList keyProperties,
+ [NotNull] IReadOnlyList keyProperties,
ValueBuffer keyValues,
[NotNull] ParameterExpression entityParameter)
{
@@ -237,7 +237,7 @@ public static Expression BuildPredicate(
static Expression GenerateEqualExpression(
Expression entityParameterExpression,
Expression keyValuesConstantExpression,
- IProperty property,
+ IReadOnlyProperty property,
int i)
=> property.ClrType.IsValueType
&& property.ClrType.UnwrapNullableType() is Type nonNullableType
diff --git a/src/EFCore/Extensions/KeyExtensions.cs b/src/EFCore/Extensions/KeyExtensions.cs
index 42176e40ae8..48d1a58c44a 100644
--- a/src/EFCore/Extensions/KeyExtensions.cs
+++ b/src/EFCore/Extensions/KeyExtensions.cs
@@ -18,7 +18,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class KeyExtensions
{
@@ -34,7 +34,7 @@ public static class KeyExtensions
/// The key metadata.
/// The type of the key instance.
/// The factory.
- public static IPrincipalKeyValueFactory GetPrincipalKeyValueFactory([NotNull] this IKey key)
+ public static IPrincipalKeyValueFactory GetPrincipalKeyValueFactory([NotNull] this IReadOnlyKey key)
=> key.AsKey().GetPrincipalKeyValueFactory();
///
@@ -42,7 +42,7 @@ public static IPrincipalKeyValueFactory GetPrincipalKeyValueFactory(
///
/// Key metadata.
/// The key type.
- public static Type GetKeyType([NotNull] this IKey key)
+ public static Type GetKeyType([NotNull] this IReadOnlyKey key)
=> key.Properties.Count > 1 ? typeof(object[]) : key.Properties.First().ClrType;
///
@@ -50,15 +50,15 @@ public static Type GetKeyType([NotNull] this IKey key)
///
/// The key to find the foreign keys for.
/// The foreign keys that reference the given key.
- public static IEnumerable GetReferencingForeignKeys([NotNull] this IKey key)
- => Check.NotNull(key, nameof(key)).AsKey().ReferencingForeignKeys ?? Enumerable.Empty();
+ public static IEnumerable GetReferencingForeignKeys([NotNull] this IReadOnlyKey key)
+ => Check.NotNull(key, nameof(key)).AsKey().ReferencingForeignKeys ?? Enumerable.Empty();
///
/// Returns a value indicating whether the key is the primary key.
///
/// The key to find whether it is primary.
/// if the key is the primary key.
- public static bool IsPrimaryKey([NotNull] this IKey key)
+ public static bool IsPrimaryKey([NotNull] this IReadOnlyKey key)
=> key == key.DeclaringEntityType.FindPrimaryKey();
///
@@ -75,7 +75,7 @@ public static bool IsPrimaryKey([NotNull] this IKey key)
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IKey key,
+ [NotNull] this IReadOnlyKey key,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/ModelExtensions.cs b/src/EFCore/Extensions/ModelExtensions.cs
index 1baf47e426b..af9049f4e08 100644
--- a/src/EFCore/Extensions/ModelExtensions.cs
+++ b/src/EFCore/Extensions/ModelExtensions.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using System.Reflection;
using System.Text;
using JetBrains.Annotations;
@@ -18,7 +19,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class ModelExtensions
{
@@ -29,31 +30,11 @@ public static class ModelExtensions
///
/// The model to find the entity type in.
/// The type to find the corresponding entity type for.
- /// The entity type, or if none if found.
+ /// The entity type, or if none is found.
[DebuggerStepThrough]
- public static IEntityType? FindEntityType([NotNull] this IModel model, [NotNull] Type type)
+ public static IReadOnlyEntityType? FindEntityType([NotNull] this IReadOnlyModel model, [NotNull] Type type)
=> ((Model)model).FindEntityType(Check.NotNull(type, nameof(type)));
- ///
- /// Gets the entity that maps the given entity class, where the class may be a proxy derived from the
- /// actual entity type. Returns if no entity type with the given CLR type is found
- /// or the given CLR type is being used by shared type entity type
- /// or the entity type has a defining navigation.
- ///
- /// The model to find the entity type in.
- /// The type to find the corresponding entity type for.
- /// The entity type, or if none if found.
- public static IEntityType? FindRuntimeEntityType([NotNull] this IModel model, [NotNull] Type type)
- {
- Check.NotNull(type, nameof(type));
- var realModel = (Model)Check.NotNull(model, nameof(model));
-
- return realModel.FindEntityType(type)
- ?? (type.BaseType == null
- ? null
- : realModel.FindEntityType(type.BaseType));
- }
-
///
/// Gets the entity type for the given type, defining navigation name
/// and the defining entity type. Returns if no matching entity type is found.
@@ -62,13 +43,13 @@ public static class ModelExtensions
/// The type of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
[DebuggerStepThrough]
- public static IEntityType? FindEntityType(
- [NotNull] this IModel model,
+ public static IReadOnlyEntityType? FindEntityType(
+ [NotNull] this IReadOnlyModel model,
[NotNull] Type type,
[NotNull] string definingNavigationName,
- [NotNull] IEntityType definingEntityType)
+ [NotNull] IReadOnlyEntityType definingEntityType)
{
Check.NotNull(model, nameof(model));
Check.NotNull(type, nameof(type));
@@ -88,7 +69,7 @@ public static class ModelExtensions
/// The type of the entity type to find.
/// The entity types found.
[DebuggerStepThrough]
- public static IEnumerable GetEntityTypes([NotNull] this IModel model, [NotNull] Type type)
+ public static IEnumerable GetEntityTypes([NotNull] this IReadOnlyModel model, [NotNull] Type type)
=> ((Model)model).GetEntityTypes(type);
///
@@ -99,7 +80,7 @@ public static IEnumerable GetEntityTypes([NotNull] this IModel mode
/// The entity types found.
[DebuggerStepThrough]
[Obsolete("Use GetEntityTypes(Type) or FindEntityType(string)")]
- public static IReadOnlyCollection GetEntityTypes([NotNull] this IModel model, [NotNull] string name)
+ public static IReadOnlyCollection GetEntityTypes([NotNull] this IReadOnlyModel model, [NotNull] string name)
=> ((Model)model).GetEntityTypes(name);
///
@@ -110,7 +91,7 @@ public static IReadOnlyCollection GetEntityTypes([NotNull] this IMo
/// if the model contains a corresponding entity type with a defining navigation.
[DebuggerStepThrough]
[Obsolete("Use IsShared(Type)")]
- public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IModel model, [NotNull] Type type)
+ public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IReadOnlyModel model, [NotNull] Type type)
=> model.IsShared(type);
///
@@ -121,9 +102,64 @@ public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IModel mod
/// if the model contains a corresponding entity type with a defining navigation.
[DebuggerStepThrough]
[Obsolete("Use FindEntityType(string)?.HasSharedClrType")]
- public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IModel model, [NotNull] string name)
+ public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IReadOnlyModel model, [NotNull] string name)
=> model.FindEntityType(name)?.HasSharedClrType ?? false;
+ ///
+ /// Returns the entity types corresponding to the least derived types from the given.
+ ///
+ /// The model to find the entity types in.
+ /// The base type.
+ /// An optional condition for filtering entity types.
+ /// List of entity types corresponding to the least derived types from the given.
+ public static IEnumerable FindLeastDerivedEntityTypes(
+ [NotNull] this IReadOnlyModel model,
+ [NotNull] Type type,
+ [CanBeNull] Func? condition = null)
+ {
+ var derivedLevels = new Dictionary { [type] = 0 };
+
+ var leastDerivedTypesGroups = model.GetEntityTypes()
+ .GroupBy(t => GetDerivedLevel(t.ClrType, derivedLevels))
+ .Where(g => g.Key != int.MaxValue)
+ .OrderBy(g => g.Key);
+
+ foreach (var leastDerivedTypes in leastDerivedTypesGroups)
+ {
+ if (condition == null)
+ {
+ return leastDerivedTypes.ToList();
+ }
+
+ var filteredTypes = leastDerivedTypes.Where(condition).ToList();
+ if (filteredTypes.Count > 0)
+ {
+ return filteredTypes;
+ }
+ }
+
+ return Enumerable.Empty();
+ }
+
+ private static int GetDerivedLevel(Type? derivedType, Dictionary derivedLevels)
+ {
+ if (derivedType?.BaseType == null)
+ {
+ return int.MaxValue;
+ }
+
+ if (derivedLevels.TryGetValue(derivedType, out var level))
+ {
+ return level;
+ }
+
+ var baseType = derivedType.BaseType;
+ level = GetDerivedLevel(baseType, derivedLevels);
+ level += level == int.MaxValue ? 0 : 1;
+ derivedLevels.Add(derivedType, level);
+ return level;
+ }
+
///
/// Gets whether the CLR type is used by shared type entities in the model.
///
@@ -131,7 +167,7 @@ public static bool HasEntityTypeWithDefiningNavigation([NotNull] this IModel mod
/// The CLR type.
/// Whether the CLR type is used by shared type entities in the model.
[DebuggerStepThrough]
- public static bool IsShared([NotNull] this IModel model, [NotNull] Type type)
+ public static bool IsShared([NotNull] this IReadOnlyModel model, [NotNull] Type type)
=> Check.NotNull(model, nameof(model)).AsModel().IsShared(Check.NotNull(type, nameof(type)));
///
@@ -141,7 +177,7 @@ public static bool IsShared([NotNull] this IModel model, [NotNull] Type type)
/// The model to get the default change tracking strategy for.
/// The change tracking strategy.
[DebuggerStepThrough]
- public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IModel model)
+ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IReadOnlyModel model)
=> ((Model)model).GetChangeTrackingStrategy();
///
@@ -155,9 +191,9 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IM
///
///
/// The model to get the access mode for.
- /// The access mode being used, or null if the default access mode is being used.
+ /// The access mode being used.
[DebuggerStepThrough]
- public static PropertyAccessMode GetPropertyAccessMode([NotNull] this IModel model)
+ public static PropertyAccessMode GetPropertyAccessMode([NotNull] this IReadOnlyModel model)
=> (PropertyAccessMode?)Check.NotNull(model, nameof(model))[CoreAnnotationNames.PropertyAccessMode]
?? PropertyAccessMode.PreferField;
@@ -165,7 +201,7 @@ public static PropertyAccessMode GetPropertyAccessMode([NotNull] this IModel mod
/// Gets the EF Core assembly version used to build this model
///
/// The model to get the version for.
- public static string? GetProductVersion([NotNull] this IModel model)
+ public static string? GetProductVersion([NotNull] this IReadOnlyModel model)
=> model[CoreAnnotationNames.ProductVersion] as string;
///
@@ -173,7 +209,7 @@ public static PropertyAccessMode GetPropertyAccessMode([NotNull] this IModel mod
///
/// The model to use.
/// The MethodInfo to check for.
- public static bool IsIndexerMethod([NotNull] this IModel model, [NotNull] MethodInfo methodInfo)
+ public static bool IsIndexerMethod([NotNull] this IReadOnlyModel model, [NotNull] MethodInfo methodInfo)
=> !methodInfo.IsStatic
&& methodInfo.IsSpecialName
&& methodInfo.DeclaringType != null
@@ -194,7 +230,7 @@ public static bool IsIndexerMethod([NotNull] this IModel model, [NotNull] Method
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IModel model,
+ [NotNull] this IReadOnlyModel model,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/MutableAnnotatableExtensions.cs b/src/EFCore/Extensions/MutableAnnotatableExtensions.cs
index 1577e8d8748..d458d0b42f9 100644
--- a/src/EFCore/Extensions/MutableAnnotatableExtensions.cs
+++ b/src/EFCore/Extensions/MutableAnnotatableExtensions.cs
@@ -24,7 +24,7 @@ public static class MutableAnnotatableExtensions
/// The key of the annotation to find.
/// The annotation with the specified name.
public static IAnnotation GetAnnotation([NotNull] this IMutableAnnotatable annotatable, [NotNull] string annotationName)
- => ((IAnnotatable)annotatable).GetAnnotation(annotationName);
+ => ((IReadOnlyAnnotatable)annotatable).GetAnnotation(annotationName);
///
/// Adds annotations to an object.
diff --git a/src/EFCore/Extensions/MutableEntityTypeExtensions.cs b/src/EFCore/Extensions/MutableEntityTypeExtensions.cs
index 2d4e3913df2..322a8c1fb0f 100644
--- a/src/EFCore/Extensions/MutableEntityTypeExtensions.cs
+++ b/src/EFCore/Extensions/MutableEntityTypeExtensions.cs
@@ -31,7 +31,7 @@ public static class MutableEntityTypeExtensions
/// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
///
public static IMutableEntityType GetRootType([NotNull] this IMutableEntityType entityType)
- => (IMutableEntityType)((IEntityType)entityType).GetRootType();
+ => (IMutableEntityType)((IReadOnlyEntityType)entityType).GetRootType();
///
/// Gets all types in the model from which a given entity type derives, starting with the root.
@@ -51,7 +51,15 @@ public static IEnumerable GetAllBaseTypes([NotNull] this IMu
/// The base types.
///
public static IEnumerable GetAllBaseTypesAscending([NotNull] this IMutableEntityType entityType)
- => entityType.GetAllBaseTypesInclusiveAscending().Skip(1).Cast();
+ => entityType.GetAllBaseTypesInclusiveAscending().Skip(1);
+
+ ///
+ /// Returns all base types of the given entity type, including the type itself, bottom to top.
+ ///
+ /// The entity type.
+ /// Base types.
+ public static IEnumerable GetAllBaseTypesInclusiveAscending([NotNull] this IMutableEntityType entityType)
+ => ((IReadOnlyEntityType)entityType).GetAllBaseTypesInclusiveAscending().Cast();
///
/// Gets all types in the model that derive from a given entity type.
@@ -79,7 +87,7 @@ public static IEnumerable GetDirectlyDerivedTypes([NotNull]
///
///
- /// Gets all keys declared on the given .
+ /// Gets all keys declared on the given .
///
///
/// This method does not return keys declared on base types.
@@ -92,6 +100,38 @@ public static IEnumerable GetDirectlyDerivedTypes([NotNull]
public static IEnumerable GetDeclaredKeys([NotNull] this IMutableEntityType entityType)
=> ((EntityType)entityType).GetDeclaredKeys();
+ ///
+ /// Gets the primary or alternate key that is defined on the given property. Returns if no key is defined
+ /// for the given property.
+ ///
+ /// The entity type.
+ /// The property that the key is defined on.
+ /// The key, or null if none is defined.
+ public static IMutableKey? FindKey([NotNull] this IMutableEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindKey(new[] { property });
+
+ ///
+ /// Adds a new alternate key to this entity type.
+ ///
+ /// The entity type.
+ /// The property to use as an alternate key.
+ /// The newly created key.
+ public static IMutableKey AddKey(
+ [NotNull] this IMutableEntityType entityType,
+ [NotNull] IMutableProperty property)
+ => Check.NotNull(entityType, nameof(entityType)).AddKey(new[] { property });
+
+ ///
+ /// Removes a primary or alternate key from this entity type.
+ ///
+ /// The entity type.
+ /// The properties that make up the key.
+ /// The removed key, or if the key was not found.
+ public static IMutableKey? RemoveKey(
+ [NotNull] this IMutableEntityType entityType,
+ [NotNull] IReadOnlyList properties)
+ => ((EntityType)entityType).RemoveKey(properties);
+
///
///
/// Gets all non-navigation properties declared on the given .
@@ -107,6 +147,15 @@ public static IEnumerable GetDeclaredKeys([NotNull] this IMutableEn
public static IEnumerable GetDeclaredProperties([NotNull] this IMutableEntityType entityType)
=> ((EntityType)entityType).GetDeclaredProperties();
+ ///
+ /// Removes a property from this entity type.
+ ///
+ /// The entity type.
+ /// The name of the property to remove.
+ /// The removed property, or if the property was not found.
+ public static IMutableProperty? RemoveProperty([NotNull] this IMutableEntityType entityType, [NotNull] string name)
+ => ((EntityType)entityType).RemoveProperty(name);
+
///
///
/// Gets all navigation properties declared on the given .
@@ -144,7 +193,7 @@ public static IEnumerable GetDeclaredServiceProperties(
///
/// This method does not return indexes declared on base types.
/// It is useful when iterating over all entity types to avoid processing the same index more than once.
- /// Use to also return indexes declared on base types.
+ /// Use to also return indexes declared on base types.
///
///
/// The entity type.
@@ -153,49 +202,45 @@ public static IEnumerable GetDeclaredIndexes([NotNull] this IMuta
=> ((EntityType)entityType).GetDeclaredIndexes();
///
- /// Removes a property from this entity type.
+ ///
+ /// Gets all indexes declared on the types derived from the given .
+ ///
///
/// The entity type.
- /// The name of the property to remove.
- /// The removed property, or if the property was not found.
- public static IMutableProperty? RemoveProperty([NotNull] this IMutableEntityType entityType, [NotNull] string name)
- => ((EntityType)entityType).RemoveProperty(name);
+ /// Derived indexes.
+ public static IEnumerable GetDerivedIndexes([NotNull] this IMutableEntityType entityType)
+ => ((EntityType)entityType).GetDerivedIndexes();
///
- /// Gets the primary or alternate key that is defined on the given property. Returns if no key is defined
- /// for the given property.
+ /// Gets the index defined on the given property. Returns null if no index is defined.
///
/// The entity type.
- /// The property that the key is defined on.
- /// The key, or null if none is defined.
- public static IMutableKey? FindKey([NotNull] this IMutableEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindKey(new[] { property });
- }
+ /// The property to find the index on.
+ /// The index, or null if none is found.
+ public static IMutableIndex? FindIndex([NotNull] this IMutableEntityType entityType, [NotNull] IReadOnlyProperty property)
+ => entityType.FindIndex(new[] { property });
///
- /// Adds a new alternate key to this entity type.
+ /// Adds an index to this entity type.
///
/// The entity type.
- /// The property to use as an alternate key.
- /// The newly created key.
- public static IMutableKey AddKey(
+ /// The property to be indexed.
+ /// The newly created index.
+ public static IMutableIndex AddIndex(
[NotNull] this IMutableEntityType entityType,
[NotNull] IMutableProperty property)
- => Check.NotNull(entityType, nameof(entityType)).AddKey(new[] { property });
+ => Check.NotNull(entityType, nameof(entityType)).AddIndex(new[] { property });
///
- /// Removes a primary or alternate key from this entity type.
+ /// Removes an index from this entity type.
///
/// The entity type.
- /// The properties that make up the key.
- /// The removed key, or if the key was not found.
- public static IMutableKey? RemoveKey(
+ /// The properties that make up the index.
+ /// The removed index, or if the index was not found.
+ public static IMutableIndex? RemoveIndex(
[NotNull] this IMutableEntityType entityType,
[NotNull] IReadOnlyList properties)
- => ((EntityType)entityType).RemoveKey(properties);
+ => ((EntityType)entityType).RemoveIndex(properties);
///
///
@@ -216,11 +261,6 @@ public static IEnumerable GetDeclaredForeignKeys([NotNull] t
///
/// Gets all foreign keys declared on the types derived from the given .
///
- ///
- /// This method does not return foreign keys declared on the given entity type itself.
- /// Use to return foreign keys declared on this
- /// and base entity typed types.
- ///
///
/// The entity type.
/// Derived foreign keys.
@@ -236,7 +276,7 @@ public static IEnumerable GetDerivedForeignKeys([NotNull] th
/// The foreign keys.
public static IEnumerable FindForeignKeys(
[NotNull] this IMutableEntityType entityType,
- [NotNull] IProperty property)
+ [NotNull] IReadOnlyProperty property)
=> entityType.FindForeignKeys(new[] { property });
///
@@ -248,7 +288,7 @@ public static IEnumerable FindForeignKeys(
/// The foreign keys.
public static IEnumerable FindForeignKeys(
[NotNull] this IMutableEntityType entityType,
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> ((EntityType)entityType).FindForeignKeys(properties);
///
@@ -266,24 +306,20 @@ public static IEnumerable FindForeignKeys(
/// The foreign key, or if none is defined.
public static IMutableForeignKey? FindForeignKey(
[NotNull] this IMutableEntityType entityType,
- [NotNull] IProperty property,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindForeignKey(new[] { property }, principalKey, principalEntityType);
- }
+ [NotNull] IReadOnlyProperty property,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
+ => entityType.FindForeignKey(new[] { property }, principalKey, principalEntityType);
///
- /// Gets the foreign keys declared on the given using the given properties.
+ /// Gets the foreign keys declared on the given using the given properties.
///
/// The entity type.
/// The properties to find the foreign keys on.
/// Declared foreign keys.
public static IEnumerable FindDeclaredForeignKeys(
[NotNull] this IMutableEntityType entityType,
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> ((EntityType)entityType).FindDeclaredForeignKeys(properties);
///
@@ -333,7 +369,7 @@ public static IMutableForeignKey AddForeignKey(
/// The entity type.
/// The relationship to the owner if this is an owned type or otherwise.
public static IMutableForeignKey? FindOwnership([NotNull] this IMutableEntityType entityType)
- => ((EntityType)entityType).FindOwnership();
+ => (IMutableForeignKey?)((IReadOnlyEntityType)entityType).FindOwnership();
///
/// Removes a foreign key from this entity type.
@@ -373,7 +409,7 @@ public static IMutableForeignKey AddForeignKey(
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
public static IMutableNavigation? FindNavigation([NotNull] this IMutableEntityType entityType, [NotNull] string name)
- => ((EntityType)entityType).FindNavigation(name);
+ => (IMutableNavigation?)((IReadOnlyEntityType)entityType).FindNavigation(name);
///
/// Gets a navigation property on the given entity type. Does not return navigation properties defined on a base type.
@@ -392,7 +428,7 @@ public static IMutableForeignKey AddForeignKey(
/// The defining navigation if one exists or otherwise.
[Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
public static IMutableNavigation? FindDefiningNavigation([NotNull] this IMutableEntityType entityType)
- => (IMutableNavigation?)((IEntityType)entityType).FindDefiningNavigation();
+ => (IMutableNavigation?)((IReadOnlyEntityType)entityType).FindDefiningNavigation();
///
/// Gets all navigation properties on the given entity type.
@@ -400,7 +436,7 @@ public static IMutableForeignKey AddForeignKey(
/// The entity type.
/// All navigation properties on the given entity type.
public static IEnumerable GetNavigations([NotNull] this IMutableEntityType entityType)
- => ((EntityType)entityType).GetNavigations();
+ => ((IReadOnlyEntityType)entityType).GetNavigations().Cast();
///
///
@@ -412,15 +448,10 @@ public static IEnumerable GetNavigations([NotNull] this IMut
///
///
/// The entity type.
- /// The property on the entity class.
+ /// The property on the entity class.
/// The property, or if none is found.
- public static IMutableProperty? FindProperty([NotNull] this IMutableEntityType entityType, [NotNull] PropertyInfo propertyInfo)
- {
- Check.NotNull(entityType, nameof(entityType));
- Check.NotNull(propertyInfo, nameof(propertyInfo));
-
- return propertyInfo.IsIndexerProperty() ? null : entityType.FindProperty(propertyInfo.GetSimpleMemberName());
- }
+ public static IMutableProperty? FindProperty([NotNull] this IMutableEntityType entityType, [NotNull] MemberInfo memberInfo)
+ => (IMutableProperty?)((IReadOnlyEntityType)entityType).FindProperty(memberInfo);
///
///
@@ -436,7 +467,24 @@ public static IEnumerable GetNavigations([NotNull] this IMut
public static IReadOnlyList? FindProperties(
[NotNull] this IMutableEntityType entityType,
[NotNull] IReadOnlyList propertyNames)
- => ((EntityType)entityType).FindProperties(Check.NotNull(propertyNames, nameof(propertyNames)));
+ => (IReadOnlyList?)((IReadOnlyEntityType)entityType).FindProperties(propertyNames);
+
+ ///
+ ///
+ /// Gets a property with the given name.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties. Use
+ /// to find a navigation property.
+ ///
+ ///
+ /// The entity type.
+ /// The property name.
+ /// The property, or if none is found.
+ public static IMutableProperty GetProperty(
+ [NotNull] this IMutableEntityType entityType,
+ [NotNull] string name)
+ => (IMutableProperty)((IReadOnlyEntityType)entityType).GetProperty(name);
///
/// Finds a property declared on the type with the given name.
@@ -508,41 +556,6 @@ public static IMutableProperty AddIndexerProperty(
return entityType.AddProperty(name, propertyType, indexerPropertyInfo);
}
- ///
- /// Gets the index defined on the given property. Returns null if no index is defined.
- ///
- /// The entity type.
- /// The property to find the index on.
- /// The index, or null if none is found.
- public static IMutableIndex? FindIndex([NotNull] this IMutableEntityType entityType, [NotNull] IProperty property)
- {
- Check.NotNull(entityType, nameof(entityType));
-
- return entityType.FindIndex(new[] { property });
- }
-
- ///
- /// Adds an index to this entity type.
- ///
- /// The entity type.
- /// The property to be indexed.
- /// The newly created index.
- public static IMutableIndex AddIndex(
- [NotNull] this IMutableEntityType entityType,
- [NotNull] IMutableProperty property)
- => Check.NotNull(entityType, nameof(entityType)).AddIndex(new[] { property });
-
- ///
- /// Removes an index from this entity type.
- ///
- /// The entity type.
- /// The properties that make up the index.
- /// The removed index, or if the index was not found.
- public static IMutableIndex? RemoveIndex(
- [NotNull] this IMutableEntityType entityType,
- [NotNull] IReadOnlyList properties)
- => ((EntityType)entityType).RemoveIndex(properties);
-
///
/// Sets the change tracking strategy to use for this entity type. This strategy indicates how the
/// context detects changes to properties for an instance of the entity type.
@@ -582,14 +595,14 @@ public static void SetDefiningQuery(
///
/// The entity type.
public static IMutableProperty? GetDiscriminatorProperty([NotNull] this IMutableEntityType entityType)
- => (IMutableProperty?)((IEntityType)entityType).GetDiscriminatorProperty();
+ => (IMutableProperty?)((IReadOnlyEntityType)entityType).GetDiscriminatorProperty();
///
- /// Sets the that will be used for storing a discriminator value.
+ /// Sets the that will be used for storing a discriminator value.
///
/// The entity type.
/// The property to set.
- public static void SetDiscriminatorProperty([NotNull] this IMutableEntityType entityType, [CanBeNull] IProperty? property)
+ public static void SetDiscriminatorProperty([NotNull] this IMutableEntityType entityType, [CanBeNull] IReadOnlyProperty? property)
=> Check.NotNull(entityType, nameof(entityType)).AsEntityType()
.SetDiscriminatorProperty((Property?)property, ConfigurationSource.Explicit);
diff --git a/src/EFCore/Extensions/MutableForeignKeyExtensions.cs b/src/EFCore/Extensions/MutableForeignKeyExtensions.cs
index 27ae946b4be..3a02951c406 100644
--- a/src/EFCore/Extensions/MutableForeignKeyExtensions.cs
+++ b/src/EFCore/Extensions/MutableForeignKeyExtensions.cs
@@ -23,7 +23,7 @@ public static class MutableForeignKeyExtensions
public static IMutableEntityType GetRelatedEntityType(
[NotNull] this IMutableForeignKey foreignKey,
[NotNull] IMutableEntityType entityType)
- => (IMutableEntityType)((IForeignKey)foreignKey).GetRelatedEntityType(entityType);
+ => (IMutableEntityType)((IReadOnlyForeignKey)foreignKey).GetRelatedEntityType(entityType);
///
/// Returns a navigation associated with this foreign key.
diff --git a/src/EFCore/Extensions/MutableKeyExtensions.cs b/src/EFCore/Extensions/MutableKeyExtensions.cs
index 6ae3b46606d..4d3b84bebe7 100644
--- a/src/EFCore/Extensions/MutableKeyExtensions.cs
+++ b/src/EFCore/Extensions/MutableKeyExtensions.cs
@@ -22,6 +22,6 @@ public static class MutableKeyExtensions
/// The key to find the foreign keys for.
/// The foreign keys that reference the given key.
public static IEnumerable GetReferencingForeignKeys([NotNull] this IMutableKey key)
- => ((IKey)key).GetReferencingForeignKeys().Cast();
+ => ((IReadOnlyKey)key).GetReferencingForeignKeys().Cast();
}
}
diff --git a/src/EFCore/Extensions/MutableModelExtensions.cs b/src/EFCore/Extensions/MutableModelExtensions.cs
index c893d72f298..2e59c0d37cb 100644
--- a/src/EFCore/Extensions/MutableModelExtensions.cs
+++ b/src/EFCore/Extensions/MutableModelExtensions.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
@@ -26,7 +27,7 @@ public static class MutableModelExtensions
///
/// The model to find the entity type in.
/// The type to find the corresponding entity type for.
- /// The entity type, or if none if found.
+ /// The entity type, or if none is found.
public static IMutableEntityType? FindEntityType([NotNull] this IMutableModel model, [NotNull] Type type)
=> ((Model)model).FindEntityType(type);
@@ -38,13 +39,13 @@ public static class MutableModelExtensions
/// The type of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
public static IMutableEntityType? FindEntityType(
[NotNull] this IMutableModel model,
[NotNull] Type type,
[NotNull] string definingNavigationName,
[NotNull] IMutableEntityType definingEntityType)
- => (IMutableEntityType?)((IModel)model).FindEntityType(type, definingNavigationName, definingEntityType);
+ => (IMutableEntityType?)((IReadOnlyModel)model).FindEntityType(type, definingNavigationName, definingEntityType);
///
/// Gets the entity types matching the given type.
@@ -146,12 +147,12 @@ public static IReadOnlyCollection GetEntityTypes([NotNull] t
/// The base type.
/// An optional condition for filtering entity types.
/// List of entity types corresponding to the least derived types from the given.
- public static IReadOnlyList FindLeastDerivedEntityTypes(
+ public static IEnumerable FindLeastDerivedEntityTypes(
[NotNull] this IMutableModel model,
[NotNull] Type type,
[CanBeNull] Func? condition = null)
- => Check.NotNull((Model)model, nameof(model))
- .FindLeastDerivedEntityTypes(type, condition);
+ => ((IReadOnlyModel)model).FindLeastDerivedEntityTypes(type, condition == null ? null : t => condition((IMutableEntityType)t))
+ .Cast();
///
/// Removes the ignored entity type.
@@ -264,8 +265,8 @@ public static void AddShared([NotNull] this IMutableModel model, [NotNull] Type
/// explicitly in cases where the automatic execution is not possible.
///
/// The model to finalize.
- /// The finalized .
+ /// The finalized model.
public static IModel FinalizeModel([NotNull] this IMutableModel model)
- => ((Model)model).FinalizeModel()!;
+ => ((Model)model).FinalizeModel();
}
}
diff --git a/src/EFCore/Extensions/MutablePropertyExtensions.cs b/src/EFCore/Extensions/MutablePropertyExtensions.cs
index 84ece9c2e8b..04dd66373e6 100644
--- a/src/EFCore/Extensions/MutablePropertyExtensions.cs
+++ b/src/EFCore/Extensions/MutablePropertyExtensions.cs
@@ -29,7 +29,7 @@ public static class MutablePropertyExtensions
/// The foreign key property.
/// The first associated principal property, or if none exists.
public static IMutableProperty? FindFirstPrincipal([NotNull] this IMutableProperty property)
- => (IMutableProperty?)((IProperty)property).FindFirstPrincipal();
+ => (IMutableProperty?)((IReadOnlyProperty)property).FindFirstPrincipal();
///
/// Finds the list of principal properties including the given property that the given property is constrained by
@@ -38,7 +38,7 @@ public static class MutablePropertyExtensions
/// The foreign key property.
/// The list of all associated principal properties including the given property.
public static IReadOnlyList FindPrincipals([NotNull] this IMutableProperty property)
- => ((IProperty)property).FindPrincipals().Cast().ToList();
+ => ((IReadOnlyProperty)property).FindPrincipals().Cast().ToList();
///
/// Gets all foreign keys that use this property (including composite foreign keys in which this property
@@ -71,7 +71,7 @@ public static IEnumerable GetContainingIndexes([NotNull] this IMu
/// The primary that use this property, or if it is not part of the primary key.
///
public static IMutableKey? FindContainingPrimaryKey([NotNull] this IMutableProperty property)
- => (IMutableKey?)((IProperty)property).FindContainingPrimaryKey();
+ => (IMutableKey?)((IReadOnlyProperty)property).FindContainingPrimaryKey();
///
/// Gets all primary or alternate keys that use this property (including composite keys in which this property
diff --git a/src/EFCore/Extensions/NavigationExtensions.cs b/src/EFCore/Extensions/NavigationExtensions.cs
index 4a52e42b6b9..c3bfe1fd178 100644
--- a/src/EFCore/Extensions/NavigationExtensions.cs
+++ b/src/EFCore/Extensions/NavigationExtensions.cs
@@ -16,7 +16,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class NavigationExtensions
{
@@ -31,7 +31,7 @@ public static class NavigationExtensions
///
[DebuggerStepThrough]
[Obsolete("Use INavigation.IsOnDependent")]
- public static bool IsDependentToPrincipal([NotNull] this INavigation navigation)
+ public static bool IsDependentToPrincipal([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsOnDependent;
///
@@ -43,7 +43,7 @@ public static bool IsDependentToPrincipal([NotNull] this INavigation navigation)
///
[DebuggerStepThrough]
[Obsolete("Use INavigation.IsCollection")]
- public static bool IsCollection([NotNull] this INavigation navigation)
+ public static bool IsCollection([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsCollection;
///
@@ -56,7 +56,7 @@ public static bool IsCollection([NotNull] this INavigation navigation)
///
[DebuggerStepThrough]
[Obsolete("Use INavigation.Inverse")]
- public static INavigation? FindInverse([NotNull] this INavigation navigation)
+ public static IReadOnlyNavigation? FindInverse([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).Inverse;
///
@@ -67,7 +67,7 @@ public static bool IsCollection([NotNull] this INavigation navigation)
/// The target entity type.
[DebuggerStepThrough]
[Obsolete("Use INavigation.TargetEntityType")]
- public static IEntityType GetTargetType([NotNull] this INavigation navigation)
+ public static IReadOnlyEntityType GetTargetType([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).TargetEntityType;
///
@@ -76,7 +76,7 @@ public static IEntityType GetTargetType([NotNull] this INavigation navigation)
/// 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)
+ public static bool IsEagerLoaded([NotNull] this IReadOnlyNavigation navigation)
=> Check.NotNull(navigation, nameof(navigation)).IsEagerLoaded;
///
@@ -93,7 +93,7 @@ public static bool IsEagerLoaded([NotNull] this INavigation navigation)
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this INavigation navigation,
+ [NotNull] this IReadOnlyNavigation navigation,
MetadataDebugStringOptions options,
int indent = 0)
{
@@ -145,9 +145,10 @@ public static string ToDebugString(
builder.Append(" PropertyAccessMode.").Append(navigation.GetPropertyAccessMode());
}
- if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0)
+ if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
+ && ((Annotatable)navigation).IsReadOnly)
{
- var indexes = navigation.GetPropertyIndexes();
+ var indexes = ((INavigation)navigation).GetPropertyIndexes();
builder.Append(" ").Append(indexes.Index);
builder.Append(" ").Append(indexes.OriginalValueIndex);
builder.Append(" ").Append(indexes.RelationshipIndex);
diff --git a/src/EFCore/Extensions/PropertyBaseExtensions.cs b/src/EFCore/Extensions/PropertyBaseExtensions.cs
index d0330222c13..48c78e999b2 100644
--- a/src/EFCore/Extensions/PropertyBaseExtensions.cs
+++ b/src/EFCore/Extensions/PropertyBaseExtensions.cs
@@ -17,7 +17,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class PropertyBaseExtensions
{
@@ -60,30 +60,16 @@ public static MemberInfo GetMemberInfo(
///
/// The property.
/// The comparer.
- public static IComparer GetCurrentValueComparer([NotNull] this IPropertyBase propertyBase)
+ public static IComparer GetCurrentValueComparer([NotNull] this IReadOnlyPropertyBase propertyBase)
=> propertyBase.AsPropertyBase().CurrentValueComparer;
- ///
- ///
- /// Gets a for reading the value of this property.
- ///
- ///
- /// Note that it is an error to call this method for a shadow property () since
- /// such a property has no associated .
- ///
- ///
- /// The property.
- /// The accessor.
- public static IClrPropertyGetter GetGetter([NotNull] this IPropertyBase propertyBase)
- => propertyBase.AsPropertyBase().Getter;
-
///
/// Gets the name of the backing field for this property, or if the backing field
/// is not known.
///
/// The property for which the backing field will be returned.
/// The name of the backing field, or .
- public static string? GetFieldName([NotNull] this IPropertyBase propertyBase)
+ public static string? GetFieldName([NotNull] this IReadOnlyPropertyBase propertyBase)
=> propertyBase.FieldInfo?.GetSimpleMemberName();
///
@@ -95,7 +81,7 @@ public static IClrPropertyGetter GetGetter([NotNull] this IPropertyBase property
///
/// if the property is a shadow property, otherwise .
///
- public static bool IsShadowProperty([NotNull] this IPropertyBase property)
+ public static bool IsShadowProperty([NotNull] this IReadOnlyPropertyBase property)
=> Check.NotNull(property, nameof(property)).GetIdentifyingMemberInfo() == null;
///
@@ -106,7 +92,7 @@ public static bool IsShadowProperty([NotNull] this IPropertyBase property)
///
/// if the property is an indexer property, otherwise .
///
- public static bool IsIndexerProperty([NotNull] this IPropertyBase property)
+ public static bool IsIndexerProperty([NotNull] this IReadOnlyPropertyBase property)
=> Check.NotNull(property, nameof(property)).GetIdentifyingMemberInfo() is PropertyInfo propertyInfo
&& propertyInfo == property.DeclaringType.FindIndexerPropertyInfo();
diff --git a/src/EFCore/Extensions/PropertyExtensions.cs b/src/EFCore/Extensions/PropertyExtensions.cs
index 062c47a66f8..c53f3375d27 100644
--- a/src/EFCore/Extensions/PropertyExtensions.cs
+++ b/src/EFCore/Extensions/PropertyExtensions.cs
@@ -23,7 +23,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class PropertyExtensions
{
@@ -32,7 +32,7 @@ public static class PropertyExtensions
///
/// The property.
/// The type mapping.
- public static CoreTypeMapping GetTypeMapping([NotNull] this IProperty property)
+ public static CoreTypeMapping GetTypeMapping([NotNull] this IReadOnlyProperty property)
{
var mapping = ((Property)property).TypeMapping;
if (mapping == null)
@@ -48,7 +48,7 @@ public static CoreTypeMapping GetTypeMapping([NotNull] this IProperty property)
///
/// The property.
/// The type mapping, or if none was found.
- public static CoreTypeMapping? FindTypeMapping([NotNull] this IProperty property)
+ public static CoreTypeMapping? FindTypeMapping([NotNull] this IReadOnlyProperty property)
=> ((Property)property).TypeMapping;
///
@@ -57,7 +57,7 @@ public static CoreTypeMapping GetTypeMapping([NotNull] this IProperty property)
///
/// The foreign key property.
/// The first associated principal property, or if none exists.
- public static IProperty? FindFirstPrincipal([NotNull] this IProperty property)
+ public static IReadOnlyProperty? FindFirstPrincipal([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -85,14 +85,14 @@ public static CoreTypeMapping GetTypeMapping([NotNull] this IProperty property)
///
/// The foreign key property.
/// The list of all associated principal properties including the given property.
- public static IReadOnlyList FindPrincipals([NotNull] this IProperty property)
+ public static IReadOnlyList FindPrincipals([NotNull] this IReadOnlyProperty property)
{
- var principals = new List { property };
+ var principals = new List { property };
AddPrincipals(property, principals);
return principals;
}
- private static void AddPrincipals(IProperty property, List visited)
+ private static void AddPrincipals(IReadOnlyProperty property, List visited)
{
var concreteProperty = property.AsProperty();
@@ -122,7 +122,7 @@ private static void AddPrincipals(IProperty property, List visited)
///
/// The property to check.
/// if the property is used as a foreign key, otherwise .
- public static bool IsForeignKey([NotNull] this IProperty property)
+ public static bool IsForeignKey([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).ForeignKeys != null;
///
@@ -130,7 +130,7 @@ public static bool IsForeignKey([NotNull] this IProperty property)
///
/// The property to check.
/// if the property is used as an index, otherwise .
- public static bool IsIndex([NotNull] this IProperty property)
+ public static bool IsIndex([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).Indexes != null;
///
@@ -138,7 +138,7 @@ public static bool IsIndex([NotNull] this IProperty property)
///
/// The property to check.
/// if the property is used as an unique index, otherwise .
- public static bool IsUniqueIndex([NotNull] this IProperty property)
+ public static bool IsUniqueIndex([NotNull] this IReadOnlyProperty property)
=> Check.NotNull(property, nameof(property)).AsProperty().Indexes?.Any(e => e.IsUnique) == true;
///
@@ -146,7 +146,7 @@ public static bool IsUniqueIndex([NotNull] this IProperty property)
///
/// The property to check.
/// if the property is used as the primary key, otherwise .
- public static bool IsPrimaryKey([NotNull] this IProperty property)
+ public static bool IsPrimaryKey([NotNull] this IReadOnlyProperty property)
=> FindContainingPrimaryKey(property) != null;
///
@@ -155,7 +155,7 @@ public static bool IsPrimaryKey([NotNull] this IProperty property)
///
/// The property to check.
/// if the property is used as a key, otherwise .
- public static bool IsKey([NotNull] this IProperty property)
+ public static bool IsKey([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).Keys != null;
///
@@ -164,7 +164,7 @@ public static bool IsKey([NotNull] this IProperty property)
///
/// The property to get foreign keys for.
/// The foreign keys that use this property.
- public static IEnumerable GetContainingForeignKeys([NotNull] this IProperty property)
+ public static IEnumerable GetContainingForeignKeys([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).GetContainingForeignKeys();
///
@@ -173,7 +173,7 @@ public static IEnumerable GetContainingForeignKeys([NotNull] this I
///
/// The property to get indexes for.
/// The indexes that use this property.
- public static IEnumerable GetContainingIndexes([NotNull] this IProperty property)
+ public static IEnumerable GetContainingIndexes([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).GetContainingIndexes();
///
@@ -182,7 +182,7 @@ public static IEnumerable GetContainingIndexes([NotNull] this IProperty
///
/// The property to get primary key for.
/// The primary that use this property, or if it is not part of the primary key.
- public static IKey? FindContainingPrimaryKey([NotNull] this IProperty property)
+ public static IReadOnlyKey? FindContainingPrimaryKey([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).PrimaryKey;
///
@@ -191,7 +191,7 @@ public static IEnumerable GetContainingIndexes([NotNull] this IProperty
///
/// The property to get primary and alternate keys for.
/// The primary and alternate keys that use this property.
- public static IEnumerable GetContainingKeys([NotNull] this IProperty property)
+ public static IEnumerable GetContainingKeys([NotNull] this IReadOnlyProperty property)
=> Check.NotNull((Property)property, nameof(property)).GetContainingKeys();
///
@@ -200,7 +200,7 @@ public static IEnumerable GetContainingKeys([NotNull] this IProperty prope
///
/// The property to get the maximum length of.
/// The maximum length, or if none if defined.
- public static int? GetMaxLength([NotNull] this IProperty property)
+ public static int? GetMaxLength([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -213,7 +213,7 @@ public static IEnumerable GetContainingKeys([NotNull] this IProperty prope
///
/// The property to get the precision of.
/// The precision, or if none is defined.
- public static int? GetPrecision([NotNull] this IProperty property)
+ public static int? GetPrecision([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -226,7 +226,7 @@ public static IEnumerable GetContainingKeys([NotNull] this IProperty prope
///
/// The property to get the scale of.
/// The scale, or if none is defined.
- public static int? GetScale([NotNull] this IProperty property)
+ public static int? GetScale([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -238,7 +238,7 @@ public static IEnumerable GetContainingKeys([NotNull] this IProperty prope
///
/// The property to get the Unicode setting for.
/// The Unicode setting, or if none is defined.
- public static bool? IsUnicode([NotNull] this IProperty property)
+ public static bool? IsUnicode([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -261,7 +261,7 @@ public static IEnumerable GetContainingKeys([NotNull] this IProperty prope
///
///
/// The property.
- public static PropertySaveBehavior GetBeforeSaveBehavior([NotNull] this IProperty property)
+ public static PropertySaveBehavior GetBeforeSaveBehavior([NotNull] this IReadOnlyProperty property)
=> (PropertySaveBehavior?)Check.NotNull(property, nameof(property))[CoreAnnotationNames.BeforeSaveBehavior]
?? (property.ValueGenerated == ValueGenerated.OnAddOrUpdate
? PropertySaveBehavior.Ignore
@@ -282,7 +282,7 @@ public static PropertySaveBehavior GetBeforeSaveBehavior([NotNull] this IPropert
///
///
/// The property.
- public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty property)
+ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IReadOnlyProperty property)
=> (PropertySaveBehavior?)Check.NotNull(property, nameof(property))[CoreAnnotationNames.AfterSaveBehavior]
?? (property.IsKey()
? PropertySaveBehavior.Throw
@@ -295,7 +295,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
///
/// The property to get the value generator factory for.
/// The factory, or if no factory has been set.
- public static Func? GetValueGeneratorFactory([NotNull] this IProperty property)
+ public static Func? GetValueGeneratorFactory([NotNull] this IReadOnlyProperty property)
=> (Func?)
Check.NotNull(property, nameof(property))[CoreAnnotationNames.ValueGeneratorFactory];
@@ -304,7 +304,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
///
/// The property.
/// The converter, or if none has been set.
- public static ValueConverter? GetValueConverter([NotNull] this IProperty property)
+ public static ValueConverter? GetValueConverter([NotNull] this IReadOnlyProperty property)
=> (ValueConverter?)Check.NotNull(property, nameof(property))[CoreAnnotationNames.ValueConverter];
///
@@ -312,7 +312,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
///
/// The property.
/// The provider type, or if none has been set.
- public static Type? GetProviderClrType([NotNull] this IProperty property)
+ public static Type? GetProviderClrType([NotNull] this IReadOnlyProperty property)
=> (Type?)Check.NotNull(property, nameof(property))[CoreAnnotationNames.ProviderClrType];
///
@@ -320,7 +320,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
///
/// The property.
/// The comparer, or if none has been set.
- public static ValueComparer? GetValueComparer([NotNull] this IProperty property)
+ public static ValueComparer? GetValueComparer([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -333,7 +333,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
///
/// The property.
/// The comparer, or if none has been set.
- public static ValueComparer? GetKeyValueComparer([NotNull] this IProperty property)
+ public static ValueComparer? GetKeyValueComparer([NotNull] this IReadOnlyProperty property)
{
Check.NotNull(property, nameof(property));
@@ -347,7 +347,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
/// The property.
/// The comparer, or if none has been set.
[Obsolete("Use GetKeyValueComparer. A separate structural comparer is no longer supported.")]
- public static ValueComparer? GetStructuralValueComparer([NotNull] this IProperty property)
+ public static ValueComparer? GetStructuralValueComparer([NotNull] this IReadOnlyProperty property)
=> property.GetKeyValueComparer();
///
@@ -356,7 +356,7 @@ public static PropertySaveBehavior GetAfterSaveBehavior([NotNull] this IProperty
/// The property.
/// The property type.
/// A new equality comparer.
- public static IEqualityComparer CreateKeyEqualityComparer([NotNull] this IProperty property)
+ public static IEqualityComparer CreateKeyEqualityComparer([NotNull] this IReadOnlyProperty property)
{
var comparer = property.GetKeyValueComparer()!;
@@ -389,7 +389,7 @@ public int GetHashCode(TNullableKey obj)
/// The properties to format.
/// If true, then type names are included in the string. The default is .
/// The string representation.
- public static string Format([NotNull] this IEnumerable properties, bool includeTypes = false)
+ public static string Format([NotNull] this IEnumerable properties, bool includeTypes = false)
=> "{"
+ string.Join(
", ",
@@ -411,7 +411,7 @@ public static string Format([NotNull] this IEnumerable properties
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IProperty property,
+ [NotNull] this IReadOnlyProperty property,
MetadataDebugStringOptions options,
int indent = 0)
{
@@ -511,17 +511,15 @@ public static string ToDebugString(
builder.Append(" PropertyAccessMode.").Append(property.GetPropertyAccessMode());
}
- if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0)
+ if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
+ && ((Annotatable)property).IsReadOnly)
{
- var indexes = property.GetPropertyIndexes();
- if (indexes != null)
- {
- 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);
- }
+ var indexes = ((IProperty)property).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)
diff --git a/src/EFCore/Extensions/ServicePropertyExtensions.cs b/src/EFCore/Extensions/ServicePropertyExtensions.cs
index e3b315dbb18..179bcd5221d 100644
--- a/src/EFCore/Extensions/ServicePropertyExtensions.cs
+++ b/src/EFCore/Extensions/ServicePropertyExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class ServicePropertyExtensions
{
@@ -30,7 +30,7 @@ public static class ServicePropertyExtensions
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this IServiceProperty serviceProperty,
+ [NotNull] this IReadOnlyServiceProperty serviceProperty,
MetadataDebugStringOptions options,
int indent = 0)
{
diff --git a/src/EFCore/Extensions/SkipNavigationExtensions.cs b/src/EFCore/Extensions/SkipNavigationExtensions.cs
index 80e1bf725b6..7655b32917b 100644
--- a/src/EFCore/Extensions/SkipNavigationExtensions.cs
+++ b/src/EFCore/Extensions/SkipNavigationExtensions.cs
@@ -14,7 +14,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class SkipNavigationExtensions
{
@@ -32,7 +32,7 @@ public static class SkipNavigationExtensions
/// The number of indent spaces to use before each new line.
/// A human-readable representation.
public static string ToDebugString(
- [NotNull] this ISkipNavigation navigation,
+ [NotNull] this IReadOnlySkipNavigation navigation,
MetadataDebugStringOptions options,
int indent = 0)
{
@@ -82,9 +82,10 @@ public static string ToDebugString(
builder.Append(" PropertyAccessMode.").Append(navigation.GetPropertyAccessMode());
}
- if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0)
+ if ((options & MetadataDebugStringOptions.IncludePropertyIndexes) != 0
+ && ((Annotatable)navigation).IsReadOnly)
{
- var indexes = navigation.GetPropertyIndexes();
+ var indexes = ((ISkipNavigation)navigation).GetPropertyIndexes();
builder.Append(" ").Append(indexes.Index);
builder.Append(" ").Append(indexes.OriginalValueIndex);
builder.Append(" ").Append(indexes.RelationshipIndex);
diff --git a/src/EFCore/Extensions/TypeBaseExtensions.cs b/src/EFCore/Extensions/TypeBaseExtensions.cs
index 9752f1f7b90..a51d7885e08 100644
--- a/src/EFCore/Extensions/TypeBaseExtensions.cs
+++ b/src/EFCore/Extensions/TypeBaseExtensions.cs
@@ -12,7 +12,7 @@
namespace Microsoft.EntityFrameworkCore
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class TypeBaseExtensions
{
@@ -26,9 +26,9 @@ public static class TypeBaseExtensions
///
///
/// The type for which to get the access mode.
- /// The access mode being used, or null if the default access mode is being used.
+ /// The access mode being used.
public static PropertyAccessMode GetPropertyAccessMode(
- [NotNull] this ITypeBase typeBase)
+ [NotNull] this IReadOnlyTypeBase typeBase)
=> (PropertyAccessMode?)Check.NotNull(typeBase, nameof(typeBase))[CoreAnnotationNames.PropertyAccessMode]
?? typeBase.Model.GetPropertyAccessMode();
@@ -42,9 +42,9 @@ public static PropertyAccessMode GetPropertyAccessMode(
///
///
/// The type for which to get the access mode.
- /// The access mode being used, or null if the default access mode is being used.
+ /// The access mode being used.
public static PropertyAccessMode GetNavigationAccessMode(
- [NotNull] this ITypeBase typeBase)
+ [NotNull] this IReadOnlyTypeBase typeBase)
=> (PropertyAccessMode?)Check.NotNull(typeBase, nameof(typeBase))[CoreAnnotationNames.NavigationAccessMode]
?? typeBase.GetPropertyAccessMode();
}
diff --git a/src/EFCore/Infrastructure/Annotatable.cs b/src/EFCore/Infrastructure/Annotatable.cs
index f321efa7cbb..b8c54b39516 100644
--- a/src/EFCore/Infrastructure/Annotatable.cs
+++ b/src/EFCore/Infrastructure/Annotatable.cs
@@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
-using System.Threading;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Internal;
@@ -26,7 +25,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
/// not used in application code.
///
///
- public class Annotatable : IMutableAnnotatable
+ public class Annotatable : IAnnotatable, IMutableAnnotatable
{
private SortedDictionary? _annotations;
private ConcurrentDictionary? _runtimeAnnotations;
@@ -38,7 +37,7 @@ public class Annotatable : IMutableAnnotatable
/// Runtime annotations cannot be changed when the object is not read-only.
///
///
- protected virtual bool IsReadOnly => false;
+ public virtual bool IsReadOnly => false;
///
/// Throws if the model is not read-only.
@@ -379,12 +378,12 @@ private ConcurrentDictionary GetOrCreateRuntimeAnnotations()
///
[DebuggerStepThrough]
- IEnumerable IAnnotatable.GetAnnotations()
+ IEnumerable IReadOnlyAnnotatable.GetAnnotations()
=> GetAnnotations();
///
[DebuggerStepThrough]
- IAnnotation? IAnnotatable.FindAnnotation(string name)
+ IAnnotation? IReadOnlyAnnotatable.FindAnnotation(string name)
=> FindAnnotation(name);
///
diff --git a/src/EFCore/Infrastructure/AnnotatableExtensions.cs b/src/EFCore/Infrastructure/AnnotatableExtensions.cs
index 17cd3b648e5..136a1937879 100644
--- a/src/EFCore/Infrastructure/AnnotatableExtensions.cs
+++ b/src/EFCore/Infrastructure/AnnotatableExtensions.cs
@@ -13,7 +13,7 @@
namespace Microsoft.EntityFrameworkCore.Infrastructure
{
///
- /// Extension methods for .
+ /// Extension methods for .
///
public static class AnnotatableExtensions
{
@@ -23,7 +23,7 @@ public static class AnnotatableExtensions
/// The object to find the annotation on.
/// The key of the annotation to find.
/// The annotation with the specified name.
- public static IAnnotation GetAnnotation([NotNull] this IAnnotatable annotatable, [NotNull] string annotationName)
+ public static IAnnotation GetAnnotation([NotNull] this IReadOnlyAnnotatable annotatable, [NotNull] string annotationName)
{
Check.NotNull(annotatable, nameof(annotatable));
Check.NotEmpty(annotationName, nameof(annotationName));
@@ -43,7 +43,7 @@ public static IAnnotation GetAnnotation([NotNull] this IAnnotatable annotatable,
/// The object to get the annotations to print in debug string.
/// The number of indent spaces to use before each new line.
/// Debug string representation of all annotations.
- public static string AnnotationsToDebugString([NotNull] this IAnnotatable annotatable, int indent = 0)
+ public static string AnnotationsToDebugString([NotNull] this IReadOnlyAnnotatable annotatable, int indent = 0)
{
var annotations = annotatable.GetAnnotations().ToList();
if (annotations.Count == 0)
diff --git a/src/EFCore/Infrastructure/Annotation.cs b/src/EFCore/Infrastructure/Annotation.cs
index fd3daf9393c..f4149b3a23e 100644
--- a/src/EFCore/Infrastructure/Annotation.cs
+++ b/src/EFCore/Infrastructure/Annotation.cs
@@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
{
///
///
- /// An arbitrary piece of metadata that can be stored on an object that implements .
+ /// An arbitrary piece of metadata that can be stored on an object that implements .
///
///
/// This type is typically used by database providers (and other extensions). It is generally
diff --git a/src/EFCore/Infrastructure/IAnnotatable.cs b/src/EFCore/Infrastructure/IAnnotatable.cs
index ad64dff61be..c09caded5e6 100644
--- a/src/EFCore/Infrastructure/IAnnotatable.cs
+++ b/src/EFCore/Infrastructure/IAnnotatable.cs
@@ -11,38 +11,15 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
{
///
///
- /// A class that exposes annotations. Annotations allow for arbitrary metadata to be stored on an object.
+ /// A class that exposes build-time and run-time annotations. Annotations allow for arbitrary metadata to be stored on an object.
///
///
/// This interface is typically used by database providers (and other extensions). It is generally
/// not used in application code.
///
///
- public interface IAnnotatable
+ public interface IAnnotatable : IReadOnlyAnnotatable
{
- ///
- /// Gets the value of the annotation with the given name, returning if it does not exist.
- ///
- /// The name of the annotation to find.
- ///
- /// The value of the existing annotation if an annotation with the specified name already exists. Otherwise, .
- ///
- object? this[[NotNull] string name] { get; }
-
- ///
- /// Gets the annotation with the given name, returning if it does not exist.
- ///
- /// The name of the annotation to find.
- ///
- /// The existing annotation if an annotation with the specified name already exists. Otherwise, .
- ///
- IAnnotation? FindAnnotation([NotNull] string name);
-
- ///
- /// Gets all annotations on the current object.
- ///
- IEnumerable GetAnnotations();
-
///
/// Gets the runtime annotation with the given name, returning if it does not exist.
///
@@ -60,8 +37,8 @@ public interface IAnnotatable
/// The value of the existing runtime annotation if an annotation with the specified name already exists.
/// Otherwise, .
///
- object? FindRuntimeAnnotationValue([NotNull] string name) =>
- FindRuntimeAnnotation(name)?.Value;
+ object? FindRuntimeAnnotationValue([NotNull] string name)
+ => FindRuntimeAnnotation(name)?.Value;
///
/// Gets all the runtime annotations on the current object.
diff --git a/src/EFCore/Infrastructure/IAnnotation.cs b/src/EFCore/Infrastructure/IAnnotation.cs
index 611a3e8f920..e4d330e0248 100644
--- a/src/EFCore/Infrastructure/IAnnotation.cs
+++ b/src/EFCore/Infrastructure/IAnnotation.cs
@@ -5,7 +5,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
{
///
///
- /// An arbitrary piece of metadata that can be stored on an object that implements .
+ /// An arbitrary piece of metadata that can be stored on an object that implements .
///
///
/// This interface is typically used by database providers (and other extensions). It is generally
diff --git a/src/EFCore/Infrastructure/IModelRuntimeInitializer.cs b/src/EFCore/Infrastructure/IModelRuntimeInitializer.cs
index 497991bf3e2..c0552c3d9ce 100644
--- a/src/EFCore/Infrastructure/IModelRuntimeInitializer.cs
+++ b/src/EFCore/Infrastructure/IModelRuntimeInitializer.cs
@@ -34,6 +34,8 @@ public interface IModelRuntimeInitializer
/// The model to initialize.
/// The validation logger.
/// The initialized model.
- IModel Initialize([NotNull] IModel model, [NotNull] IDiagnosticsLogger? validationLogger);
+ IModel Initialize(
+ [NotNull] IModel model,
+ [NotNull] IDiagnosticsLogger? validationLogger);
}
}
diff --git a/src/EFCore/Infrastructure/IReadOnlyAnnotatable.cs b/src/EFCore/Infrastructure/IReadOnlyAnnotatable.cs
new file mode 100644
index 00000000000..8b9cfd5bc0f
--- /dev/null
+++ b/src/EFCore/Infrastructure/IReadOnlyAnnotatable.cs
@@ -0,0 +1,45 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using JetBrains.Annotations;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Infrastructure
+{
+ ///
+ ///
+ /// A class that supports annotations. Annotations allow for arbitrary metadata to be stored on an object.
+ ///
+ ///
+ /// This interface is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ public interface IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the value of the annotation with the given name, returning if it does not exist.
+ ///
+ /// The name of the annotation to find.
+ ///
+ /// The value of the existing annotation if an annotation with the specified name already exists. Otherwise, .
+ ///
+ object? this[[NotNull] string name] { get; }
+
+ ///
+ /// Gets the annotation with the given name, returning if it does not exist.
+ ///
+ /// The name of the annotation to find.
+ ///
+ /// The existing annotation if an annotation with the specified name already exists. Otherwise, .
+ ///
+ IAnnotation? FindAnnotation([NotNull] string name);
+
+ ///
+ /// Gets all annotations on the current object.
+ ///
+ IEnumerable GetAnnotations();
+ }
+}
diff --git a/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs b/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs
index 71a51627c4a..1b3db088bfc 100644
--- a/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs
+++ b/src/EFCore/Infrastructure/ModelRuntimeInitializer.cs
@@ -49,7 +49,9 @@ public ModelRuntimeInitializer([NotNull] ModelRuntimeInitializerDependencies dep
/// The model to initialize.
/// The validation logger.
/// The initialized model.
- public virtual IModel Initialize(IModel model, IDiagnosticsLogger? validationLogger)
+ public virtual IModel Initialize(
+ IModel model,
+ IDiagnosticsLogger? validationLogger)
{
if (model.SetModelDependencies(Dependencies.ModelDependencies))
{
diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs
index 405f614e1fc..10b6bf9e5e0 100644
--- a/src/EFCore/Infrastructure/ModelValidator.cs
+++ b/src/EFCore/Infrastructure/ModelValidator.cs
@@ -1122,7 +1122,7 @@ protected virtual void LogShadowProperties(
{
if (property.IsImplicitlyCreated())
{
- logger.ShadowPropertyCreated(property);
+ logger.ShadowPropertyCreated((IProperty)property);
}
}
}
diff --git a/src/EFCore/Infrastructure/NavigationBaseExtensions.cs b/src/EFCore/Infrastructure/NavigationBaseExtensions.cs
deleted file mode 100644
index d80a68559fe..00000000000
--- a/src/EFCore/Infrastructure/NavigationBaseExtensions.cs
+++ /dev/null
@@ -1,46 +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.Linq;
-using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Utilities;
-
-namespace Microsoft.EntityFrameworkCore.Infrastructure
-{
- ///
- ///
- /// Extension methods for .
- ///
- ///
- /// This type is typically used by database providers (and other extensions). It is generally
- /// not used in application code.
- ///
- ///
- public static class NavigationBaseExtensions
- {
- ///
- /// Calls for a to mark it as loaded
- /// when a no-tracking query has eagerly loaded this relationship.
- ///
- /// The navigation loaded.
- /// The entity for which the navigation has been loaded.
- public static void SetIsLoadedWhenNoTracking([NotNull] this INavigationBase navigation, [NotNull] object entity)
- {
- Check.NotNull(navigation, nameof(navigation));
- Check.NotNull(entity, nameof(entity));
-
- var serviceProperties = navigation
- .DeclaringEntityType
- .GetDerivedTypesInclusive()
- .Where(t => t.ClrType.IsInstanceOfType(entity))
- .SelectMany(e => e.GetServiceProperties())
- .Where(p => p.ClrType == typeof(ILazyLoader));
-
- foreach (var serviceProperty in serviceProperties)
- {
- ((ILazyLoader)serviceProperty.GetGetter().GetClrValue(entity))?.SetLoaded(entity, navigation.Name);
- }
- }
- }
-}
diff --git a/src/EFCore/Infrastructure/SingletonModelDependencies.cs b/src/EFCore/Infrastructure/SingletonModelDependencies.cs
index aaafa61b2e3..8f8d73286bd 100644
--- a/src/EFCore/Infrastructure/SingletonModelDependencies.cs
+++ b/src/EFCore/Infrastructure/SingletonModelDependencies.cs
@@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
{
///
///
- /// Service dependencies parameter class for
+ /// Service dependencies parameter class for
///
///
/// This type is typically used by database providers (and other extensions). It is generally
diff --git a/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs b/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs
index cfeb1929b97..2062d315fcd 100644
--- a/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs
+++ b/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs
@@ -601,7 +601,7 @@ IConventionEntityTypeBuilder RemoveUnusedShadowProperties(
/// The same builder instance if the skip navigation was removed,
/// otherwise.
///
- IConventionEntityTypeBuilder? HasNoSkipNavigation([NotNull] ISkipNavigation skipNavigation, bool fromDataAnnotation = false);
+ IConventionEntityTypeBuilder? HasNoSkipNavigation([NotNull] IReadOnlySkipNavigation skipNavigation, bool fromDataAnnotation = false);
///
/// Returns a value indicating whether the skip navigation can be removed from this entity type.
@@ -609,7 +609,7 @@ IConventionEntityTypeBuilder RemoveUnusedShadowProperties(
/// The skip navigation to be removed.
/// Indicates whether the configuration was specified using a data annotation.
/// if the skip navigation can be removed from this entity type.
- bool CanRemoveSkipNavigation([NotNull] ISkipNavigation skipNavigation, bool fromDataAnnotation = false);
+ bool CanRemoveSkipNavigation([NotNull] IReadOnlySkipNavigation skipNavigation, bool fromDataAnnotation = false);
///
/// Returns a value indicating whether the given navigation can be added to this entity type.
diff --git a/src/EFCore/Metadata/Builders/NavigationBuilder.cs b/src/EFCore/Metadata/Builders/NavigationBuilder.cs
index 4e052bf1cc0..7039303d872 100644
--- a/src/EFCore/Metadata/Builders/NavigationBuilder.cs
+++ b/src/EFCore/Metadata/Builders/NavigationBuilder.cs
@@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders
{
///
///
- /// Provides a simple API for configuring a or .
+ /// Provides a simple API for configuring a or .
///
///
/// Instances of this class are returned from methods when using the API
diff --git a/src/EFCore/Metadata/Builders/NavigationBuilder`.cs b/src/EFCore/Metadata/Builders/NavigationBuilder`.cs
index 51f6d7d44f4..63103341a92 100644
--- a/src/EFCore/Metadata/Builders/NavigationBuilder`.cs
+++ b/src/EFCore/Metadata/Builders/NavigationBuilder`.cs
@@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders
{
///
///
- /// Provides a simple API for configuring a or .
+ /// Provides a simple API for configuring a or a .
///
///
/// Instances of this class are returned from methods when using the API
diff --git a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs
index cf986f31682..12183b86f4b 100644
--- a/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs
+++ b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs
@@ -158,7 +158,7 @@ public virtual void ProcessModelFinalizing(
}
}
- private static string FormatConstructorString(IEntityType entityType, InstantiationBinding binding)
+ private static string FormatConstructorString(IReadOnlyEntityType entityType, InstantiationBinding binding)
=> entityType.ClrType.ShortDisplayName()
+ "("
+ string.Join(", ", binding.ParameterBindings.Select(b => b.ParameterType.ShortDisplayName()))
diff --git a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs
index 5a17850fc3d..9189a1e7687 100644
--- a/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs
+++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs
@@ -872,7 +872,7 @@ public virtual void ProcessModelFinalizing(
///
/// The foreign key.
/// The string that should be used as part of the shadow properties created for the given foreign key.
- public static string GetPropertyBaseName([NotNull] IForeignKey foreignKey)
+ public static string GetPropertyBaseName([NotNull] IReadOnlyForeignKey foreignKey)
=> foreignKey.DependentToPrincipal?.Name
?? foreignKey.GetReferencingSkipNavigations().FirstOrDefault()?.Inverse?.Name
?? foreignKey.PrincipalEntityType.ShortName();
diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs
index 78d3f5129d0..0003db732a6 100644
--- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs
+++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs
@@ -66,18 +66,18 @@ public ImmediateConventionScope([NotNull] ConventionSet conventionSet, Conventio
public override void Run(ConventionDispatcher dispatcher)
=> Check.DebugAssert(false, "Immediate convention scope cannot be run again.");
- public IConventionModelBuilder? OnModelFinalizing([NotNull] IConventionModelBuilder modelBuilder)
+ public IConventionModelBuilder OnModelFinalizing([NotNull] IConventionModelBuilder modelBuilder)
{
_modelBuilderConventionContext.ResetState(modelBuilder);
foreach (var modelConvention in _conventionSet.ModelFinalizingConventions)
{
- // Execute each convention in a separate batch so model validation will get an up-to-date model
+ // Execute each convention in a separate batch so each will get an up-to-date model as they are meant to be only run once
using (_dispatcher.DelayConventions())
{
modelConvention.ProcessModelFinalizing(modelBuilder, _modelBuilderConventionContext);
if (_modelBuilderConventionContext.ShouldStopProcessing())
{
- return _modelBuilderConventionContext.Result;
+ return _modelBuilderConventionContext.Result!;
}
}
}
@@ -85,7 +85,7 @@ public override void Run(ConventionDispatcher dispatcher)
return modelBuilder;
}
- public IModel? OnModelFinalized([NotNull] IModel model)
+ public IModel OnModelFinalized([NotNull] IModel model)
{
foreach (var modelConvention in _conventionSet.ModelFinalizedConventions)
{
@@ -95,7 +95,7 @@ public override void Run(ConventionDispatcher dispatcher)
return model;
}
- public IConventionModelBuilder? OnModelInitialized([NotNull] IConventionModelBuilder modelBuilder)
+ public IConventionModelBuilder OnModelInitialized([NotNull] IConventionModelBuilder modelBuilder)
{
using (_dispatcher.DelayConventions())
{
@@ -105,7 +105,7 @@ public override void Run(ConventionDispatcher dispatcher)
modelConvention.ProcessModelInitialized(modelBuilder, _modelBuilderConventionContext);
if (_modelBuilderConventionContext.ShouldStopProcessing())
{
- return _modelBuilderConventionContext.Result;
+ return _modelBuilderConventionContext.Result!;
}
}
}
diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.cs
index d02a732acad..1871f56708f 100644
--- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.cs
+++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.cs
@@ -54,7 +54,7 @@ public ConventionDispatcher([NotNull] ConventionSet conventionSet)
/// 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 IConventionModelBuilder? OnModelInitialized([NotNull] IConventionModelBuilder modelBuilder)
+ public virtual IConventionModelBuilder OnModelInitialized([NotNull] IConventionModelBuilder modelBuilder)
=> _immediateConventionScope.OnModelInitialized(modelBuilder);
///
@@ -63,7 +63,7 @@ public ConventionDispatcher([NotNull] ConventionSet conventionSet)
/// 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 IConventionModelBuilder? OnModelFinalizing([NotNull] IConventionModelBuilder modelBuilder)
+ public virtual IConventionModelBuilder OnModelFinalizing([NotNull] IConventionModelBuilder modelBuilder)
=> _immediateConventionScope.OnModelFinalizing(modelBuilder);
///
@@ -72,7 +72,7 @@ public ConventionDispatcher([NotNull] ConventionSet conventionSet)
/// 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 IModel? OnModelFinalized([NotNull] IModel model)
+ public virtual IModel OnModelFinalized([NotNull] IModel model)
=> _immediateConventionScope.OnModelFinalized(model);
///
diff --git a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs
index 9dfdffb62f4..f4b84219f7f 100644
--- a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs
+++ b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs
@@ -309,11 +309,14 @@ public override void ProcessEntityTypeRemoved(
return;
}
- var leastDerivedEntityTypes = modelBuilder.Metadata.FindLeastDerivedEntityTypes(
- declaringType,
- t => !t.Builder.IsIgnored(navigationMemberInfo.GetSimpleMemberName(), fromDataAnnotation: true));
+ var leastDerivedEntityTypes = modelBuilder.Metadata.FindLeastDerivedEntityTypes(declaringType);
foreach (var leastDerivedEntityType in leastDerivedEntityTypes)
{
+ if (leastDerivedEntityType.Builder.IsIgnored(navigationMemberInfo.GetSimpleMemberName(), fromDataAnnotation: true))
+ {
+ continue;
+ }
+
Process(leastDerivedEntityType.Builder, navigationMemberInfo, targetClrType, attribute);
}
}
diff --git a/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs b/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs
index 970932ab64f..5ce3c93f3b7 100644
--- a/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs
+++ b/src/EFCore/Metadata/Conventions/QueryFilterRewritingConvention.cs
@@ -61,7 +61,7 @@ public virtual void ProcessModelFinalizing(
protected class DbSetAccessRewritingExpressionVisitor : ExpressionVisitor
{
private readonly Type _contextType;
- private IModel? _model;
+ private IReadOnlyModel? _model;
///
/// Creates a new instance of .
@@ -77,7 +77,7 @@ public DbSetAccessRewritingExpressionVisitor(Type contextType)
///
/// The model to look for entity types.
/// The query expression to rewrite.
- public Expression Rewrite(IModel model, Expression expression)
+ public Expression Rewrite(IReadOnlyModel model, Expression expression)
{
_model = model;
@@ -121,7 +121,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
}
private IEntityType? FindEntityType(Type dbSetType)
- => _model!.FindRuntimeEntityType(dbSetType.GetGenericArguments()[0]);
+ => ((IModel)_model!).FindRuntimeEntityType(dbSetType.GetGenericArguments()[0]);
}
}
}
diff --git a/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs b/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs
index 27bfda97277..cdf1830e19d 100644
--- a/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs
+++ b/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs
@@ -38,7 +38,7 @@ public virtual void ProcessModelFinalizing(
{
foreach (var property in modelBuilder.Metadata.GetEntityTypes().SelectMany(e => e.GetDeclaredProperties()))
{
- property.Builder.HasTypeMapping(Dependencies.TypeMappingSource.FindMapping(property));
+ property.Builder.HasTypeMapping(Dependencies.TypeMappingSource.FindMapping((IProperty)property));
}
}
}
diff --git a/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs b/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs
index 69e262f1fb2..2875e02ed6b 100644
--- a/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs
+++ b/src/EFCore/Metadata/Conventions/ValueGenerationConvention.cs
@@ -185,21 +185,21 @@ public virtual void ProcessEntityTypeBaseTypeChanged(
/// The property.
/// The store value generation strategy to set for the given property.
protected virtual ValueGenerated? GetValueGenerated([NotNull] IConventionProperty property)
- => GetValueGenerated((IProperty)property);
+ => GetValueGenerated((IReadOnlyProperty)property);
///
/// Returns the store value generation strategy to set for the given property.
///
/// The property.
/// The store value generation strategy to set for the given property.
- public static ValueGenerated? GetValueGenerated([NotNull] IProperty property)
+ public static ValueGenerated? GetValueGenerated([NotNull] IReadOnlyProperty property)
=> !property.GetContainingForeignKeys().Any(fk => !fk.IsBaseLinking())
&& ShouldHaveGeneratedProperty(property.FindContainingPrimaryKey())
&& CanBeGenerated(property)
? ValueGenerated.OnAdd
: (ValueGenerated?)null;
- private static bool ShouldHaveGeneratedProperty(IKey? key)
+ private static bool ShouldHaveGeneratedProperty(IReadOnlyKey? key)
=> key != null
&& key.DeclaringEntityType.IsOwned() is var onOwnedType
&& (onOwnedType && key.Properties.Count(p => !p.IsForeignKey()) == 1
@@ -211,7 +211,7 @@ private static bool ShouldHaveGeneratedProperty(IKey? key)
///
/// The key property that might be store generated.
/// A value indicating whether the specified property should have the value generated by the store.
- private static bool CanBeGenerated(IProperty property)
+ private static bool CanBeGenerated(IReadOnlyProperty property)
{
var propertyType = property.ClrType.UnwrapNullableType();
return (propertyType.IsInteger()
diff --git a/src/EFCore/Metadata/EntityTypeFullNameComparer.cs b/src/EFCore/Metadata/EntityTypeFullNameComparer.cs
index 0919a88ca7d..d546fbdfffa 100644
--- a/src/EFCore/Metadata/EntityTypeFullNameComparer.cs
+++ b/src/EFCore/Metadata/EntityTypeFullNameComparer.cs
@@ -11,14 +11,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// An implementation of and to compare
- /// instances by name including the defining entity type when present.
+ /// instances by name including the defining entity type when present.
///
///
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
///
///
- public sealed class EntityTypeFullNameComparer : IComparer, IEqualityComparer
+ public sealed class EntityTypeFullNameComparer : IComparer, IEqualityComparer
{
private EntityTypeFullNameComparer()
{
@@ -35,7 +35,7 @@ private EntityTypeFullNameComparer()
/// The first object to compare.
/// The second object to compare.
/// A negative number if 'x' is less than 'y'; a positive number if 'x' is greater than 'y'; zero otherwise.
- public int Compare(IEntityType? x, IEntityType? y)
+ public int Compare(IReadOnlyEntityType? x, IReadOnlyEntityType? y)
{
if (ReferenceEquals(x, y))
{
@@ -61,7 +61,7 @@ public int Compare(IEntityType? x, IEntityType? y)
/// The first object to compare.
/// The second object to compare.
/// if the specified objects are equal; otherwise, .
- public bool Equals(IEntityType? x, IEntityType? y)
+ public bool Equals(IReadOnlyEntityType? x, IReadOnlyEntityType? y)
=> Compare(x, y) == 0;
///
@@ -69,7 +69,7 @@ public bool Equals(IEntityType? x, IEntityType? y)
///
/// The for which a hash code is to be returned.
/// A hash code for the specified object.
- public int GetHashCode(IEntityType obj)
+ public int GetHashCode(IReadOnlyEntityType obj)
=> obj.Name.GetHashCode();
}
}
diff --git a/src/EFCore/Metadata/ForeignKeyComparer.cs b/src/EFCore/Metadata/ForeignKeyComparer.cs
index 68c517c45c0..0281a067dbf 100644
--- a/src/EFCore/Metadata/ForeignKeyComparer.cs
+++ b/src/EFCore/Metadata/ForeignKeyComparer.cs
@@ -12,14 +12,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// An implementation of and to compare
- /// instances.
+ /// instances.
///
///
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
///
///
- public sealed class ForeignKeyComparer : IEqualityComparer, IComparer
+ public sealed class ForeignKeyComparer : IEqualityComparer, IComparer
{
private ForeignKeyComparer()
{
@@ -36,7 +36,7 @@ private ForeignKeyComparer()
/// The first object to compare.
/// The second object to compare.
/// A negative number if 'x' is less than 'y'; a positive number if 'x' is greater than 'y'; zero otherwise.
- public int Compare(IForeignKey? x, IForeignKey? y)
+ public int Compare(IReadOnlyForeignKey? x, IReadOnlyForeignKey? y)
{
var result = PropertyListComparer.Instance.Compare(x?.Properties, y?.Properties);
if (result != 0)
@@ -60,7 +60,7 @@ public int Compare(IForeignKey? x, IForeignKey? y)
/// The first object to compare.
/// The second object to compare.
/// if the specified objects are equal; otherwise, .
- public bool Equals(IForeignKey? x, IForeignKey? y)
+ public bool Equals(IReadOnlyForeignKey? x, IReadOnlyForeignKey? y)
=> Compare(x, y) == 0;
///
@@ -68,7 +68,7 @@ public bool Equals(IForeignKey? x, IForeignKey? y)
///
/// The for which a hash code is to be returned.
/// A hash code for the specified object.
- public int GetHashCode(IForeignKey obj)
+ public int GetHashCode(IReadOnlyForeignKey obj)
{
var hashCode = new HashCode();
hashCode.Add(obj.PrincipalKey.Properties, PropertyListComparer.Instance);
diff --git a/src/EFCore/Metadata/IConstructorBindingFactory.cs b/src/EFCore/Metadata/IConstructorBindingFactory.cs
index d6a70ac3fd1..9e3fbfde1ca 100644
--- a/src/EFCore/Metadata/IConstructorBindingFactory.cs
+++ b/src/EFCore/Metadata/IConstructorBindingFactory.cs
@@ -25,7 +25,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
public interface IConstructorBindingFactory
{
///
- /// Attempts to create a for the given and
+ /// Attempts to create a for the given entity type and
///
///
/// The entity type.
@@ -40,7 +40,7 @@ bool TryBindConstructor(
[CanBeNull, CA.NotNullWhen(false)] out IEnumerable? unboundParameters);
///
- /// Attempts to create a for the given and
+ /// Attempts to create a for the given entity type and
///
///
/// The entity type.
diff --git a/src/EFCore/Metadata/IConventionAnnotatable.cs b/src/EFCore/Metadata/IConventionAnnotatable.cs
index 7d9bf1853a0..91d0c5f5d98 100644
--- a/src/EFCore/Metadata/IConventionAnnotatable.cs
+++ b/src/EFCore/Metadata/IConventionAnnotatable.cs
@@ -21,7 +21,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// not used in application code.
///
///
- public interface IConventionAnnotatable : IAnnotatable
+ public interface IConventionAnnotatable : IReadOnlyAnnotatable
{
///
/// Gets the builder that can be used to configure this object.
diff --git a/src/EFCore/Metadata/IConventionEntityType.cs b/src/EFCore/Metadata/IConventionEntityType.cs
index e9ec3de6160..e1f9f07bf48 100644
--- a/src/EFCore/Metadata/IConventionEntityType.cs
+++ b/src/EFCore/Metadata/IConventionEntityType.cs
@@ -14,14 +14,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// Represents an entity in an .
+ /// Represents an entity type in an .
///
///
/// 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 IConventionEntityType : IEntityType, IConventionTypeBase
+ public interface IConventionEntityType : IReadOnlyEntityType, IConventionTypeBase
{
///
/// Gets the configuration source for this entity type.
@@ -152,7 +152,7 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
///
/// The properties that make up the key.
/// The key, or if none is defined.
- new IConventionKey? FindKey([NotNull] IReadOnlyList properties);
+ new IConventionKey? FindKey([NotNull] IReadOnlyList properties);
///
/// Gets the primary and alternate keys for this entity type.
@@ -202,9 +202,9 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
///
/// The foreign key, or if none is defined.
new IConventionForeignKey? FindForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType);
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType);
///
/// Gets the foreign keys defined on this entity type.
@@ -252,7 +252,7 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
/// The navigation property on the entity class.
/// The navigation property, or if none is found.
new IConventionSkipNavigation? FindSkipNavigation([NotNull] MemberInfo memberInfo)
- => (IConventionSkipNavigation?)((IEntityType)this).FindSkipNavigation(memberInfo);
+ => (IConventionSkipNavigation?)((IReadOnlyEntityType)this).FindSkipNavigation(memberInfo);
///
/// Gets a skip navigation property on this entity type. Returns if no skip navigation property is found.
@@ -268,7 +268,7 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
new IConventionSkipNavigation? FindDeclaredSkipNavigation([NotNull] string name)
- => (IConventionSkipNavigation?)((IEntityType)this).FindDeclaredSkipNavigation(name);
+ => (IConventionSkipNavigation?)((IReadOnlyEntityType)this).FindDeclaredSkipNavigation(name);
///
///
@@ -282,7 +282,7 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
///
/// Declared foreign keys.
new IEnumerable GetDeclaredSkipNavigations()
- => ((IEntityType)this).GetDeclaredSkipNavigations().Cast();
+ => ((IReadOnlyEntityType)this).GetDeclaredSkipNavigations().Cast();
///
/// Gets all skip navigation properties on this entity type.
@@ -329,7 +329,7 @@ void HasNoKey(bool? keyless, bool fromDataAnnotation = false)
///
/// The properties to find the index on.
/// The index, or if none is found.
- new IConventionIndex? FindIndex([NotNull] IReadOnlyList properties);
+ new IConventionIndex? FindIndex([NotNull] IReadOnlyList properties);
///
/// Gets the index with the given name. Returns if no such index exists.
diff --git a/src/EFCore/Metadata/IConventionForeignKey.cs b/src/EFCore/Metadata/IConventionForeignKey.cs
index fb6ca4257b2..52bd964f0be 100644
--- a/src/EFCore/Metadata/IConventionForeignKey.cs
+++ b/src/EFCore/Metadata/IConventionForeignKey.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionForeignKey : IForeignKey, IConventionAnnotatable
+ public interface IConventionForeignKey : IReadOnlyForeignKey, IConventionAnnotatable
{
///
/// Gets the builder that can be used to configure this foreign key.
@@ -83,21 +83,21 @@ IReadOnlyList SetProperties(
bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetPropertiesConfigurationSource();
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetPrincipalKeyConfigurationSource();
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetPrincipalEndConfigurationSource();
///
@@ -109,9 +109,9 @@ IReadOnlyList SetProperties(
bool? SetIsUnique(bool? unique, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsUniqueConfigurationSource();
///
@@ -124,9 +124,9 @@ IReadOnlyList SetProperties(
bool? SetIsRequired(bool? required, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsRequiredConfigurationSource();
///
@@ -139,9 +139,9 @@ IReadOnlyList SetProperties(
bool? SetIsRequiredDependent(bool? required, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsRequiredDependentConfigurationSource();
///
@@ -154,9 +154,9 @@ IReadOnlyList SetProperties(
bool? SetIsOwnership(bool? ownership, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsOwnershipConfigurationSource();
///
@@ -172,9 +172,9 @@ IReadOnlyList SetProperties(
DeleteBehavior? SetDeleteBehavior(DeleteBehavior? deleteBehavior, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetDeleteBehaviorConfigurationSource();
///
@@ -226,9 +226,9 @@ IReadOnlyList SetProperties(
=> SetDependentToPrincipal(property, fromDataAnnotation);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetDependentToPrincipalConfigurationSource();
///
@@ -280,9 +280,9 @@ IReadOnlyList SetProperties(
=> SetPrincipalToDependent(property, fromDataAnnotation);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetPrincipalToDependentConfigurationSource();
///
@@ -290,6 +290,6 @@ IReadOnlyList SetProperties(
///
/// The skip navigations using this foreign key.
new IEnumerable GetReferencingSkipNavigations()
- => ((IForeignKey)this).GetReferencingSkipNavigations().Cast();
+ => ((IReadOnlyForeignKey)this).GetReferencingSkipNavigations().Cast();
}
}
diff --git a/src/EFCore/Metadata/IConventionIndex.cs b/src/EFCore/Metadata/IConventionIndex.cs
index a5babbab0d7..7c9a5c8cd1c 100644
--- a/src/EFCore/Metadata/IConventionIndex.cs
+++ b/src/EFCore/Metadata/IConventionIndex.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionIndex : IIndex, IConventionAnnotatable
+ public interface IConventionIndex : IReadOnlyIndex, IConventionAnnotatable
{
///
/// Gets the builder that can be used to configure this index.
@@ -53,9 +53,9 @@ public interface IConventionIndex : IIndex, IConventionAnnotatable
bool? SetIsUnique(bool? unique, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsUniqueConfigurationSource();
}
}
diff --git a/src/EFCore/Metadata/IConventionKey.cs b/src/EFCore/Metadata/IConventionKey.cs
index bd99d40e537..c87adc053c5 100644
--- a/src/EFCore/Metadata/IConventionKey.cs
+++ b/src/EFCore/Metadata/IConventionKey.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionKey : IConventionAnnotatable, IKey
+ public interface IConventionKey : IReadOnlyKey, IConventionAnnotatable
{
///
/// Gets the builder that can be used to configure this key.
diff --git a/src/EFCore/Metadata/IConventionModel.cs b/src/EFCore/Metadata/IConventionModel.cs
index b7a1943edc7..784289a92e8 100644
--- a/src/EFCore/Metadata/IConventionModel.cs
+++ b/src/EFCore/Metadata/IConventionModel.cs
@@ -23,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionModel : IModel, IConventionAnnotatable
+ public interface IConventionModel : IReadOnlyModel, IConventionAnnotatable
{
///
/// Gets the builder that can be used to configure this model.
@@ -113,7 +113,7 @@ public interface IConventionModel : IModel, IConventionAnnotatable
/// or the entity type has a defining navigation.
///
/// The name of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
new IConventionEntityType? FindEntityType([NotNull] string name);
///
@@ -123,7 +123,7 @@ public interface IConventionModel : IModel, IConventionAnnotatable
/// The name of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
IConventionEntityType? FindEntityType(
[NotNull] string name,
[NotNull] string definingNavigationName,
diff --git a/src/EFCore/Metadata/IConventionNavigation.cs b/src/EFCore/Metadata/IConventionNavigation.cs
index d759ba0587c..3a5f6e69df5 100644
--- a/src/EFCore/Metadata/IConventionNavigation.cs
+++ b/src/EFCore/Metadata/IConventionNavigation.cs
@@ -20,7 +20,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionNavigation : INavigation, IConventionNavigationBase
+ public interface IConventionNavigation : IReadOnlyNavigation, IConventionNavigationBase
{
///
/// Gets the builder that can be used to configure this navigation.
@@ -34,7 +34,7 @@ public interface IConventionNavigation : INavigation, IConventionNavigationBase
new IConventionEntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => (IConventionEntityType)((INavigationBase)this).DeclaringEntityType;
+ get => (IConventionEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
}
///
@@ -43,7 +43,7 @@ public interface IConventionNavigation : INavigation, IConventionNavigationBase
new IConventionEntityType TargetEntityType
{
[DebuggerStepThrough]
- get => (IConventionEntityType)((INavigationBase)this).TargetEntityType;
+ get => (IConventionEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
@@ -61,7 +61,7 @@ ConfigurationSource IConventionPropertyBase.GetConfigurationSource()
new IConventionForeignKey ForeignKey
{
[DebuggerStepThrough]
- get => (IConventionForeignKey)((INavigation)this).ForeignKey;
+ get => (IConventionForeignKey)((IReadOnlyNavigation)this).ForeignKey;
}
///
@@ -70,7 +70,7 @@ ConfigurationSource IConventionPropertyBase.GetConfigurationSource()
new IConventionNavigation? Inverse
{
[DebuggerStepThrough]
- get => (IConventionNavigation?)((INavigation)this).Inverse;
+ get => (IConventionNavigation?)((IReadOnlyNavigation)this).Inverse;
}
///
diff --git a/src/EFCore/Metadata/IConventionNavigationBase.cs b/src/EFCore/Metadata/IConventionNavigationBase.cs
index a6d856274fb..bfb0a14270b 100644
--- a/src/EFCore/Metadata/IConventionNavigationBase.cs
+++ b/src/EFCore/Metadata/IConventionNavigationBase.cs
@@ -13,10 +13,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionNavigationBase : INavigationBase, IConventionPropertyBase
+ public interface IConventionNavigationBase : IReadOnlyNavigationBase, IConventionPropertyBase
{
///
/// Sets a value indicating whether this navigation should be eager loaded by default.
diff --git a/src/EFCore/Metadata/IConventionProperty.cs b/src/EFCore/Metadata/IConventionProperty.cs
index 6ad6c5e3753..07058e7730b 100644
--- a/src/EFCore/Metadata/IConventionProperty.cs
+++ b/src/EFCore/Metadata/IConventionProperty.cs
@@ -10,14 +10,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// Represents a scalar property of an entity.
+ /// Represents a scalar property of an entity type.
///
///
/// 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 IConventionProperty : IProperty, IConventionPropertyBase
+ public interface IConventionProperty : IReadOnlyProperty, IConventionPropertyBase
{
///
/// Gets the builder that can be used to configure this property.
@@ -31,9 +31,9 @@ public interface IConventionProperty : IProperty, IConventionPropertyBase
new IConventionEntityType DeclaringEntityType { get; }
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetTypeConfigurationSource();
///
@@ -48,9 +48,9 @@ public interface IConventionProperty : IProperty, IConventionPropertyBase
bool? SetIsNullable(bool? nullable, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsNullableConfigurationSource();
///
@@ -69,9 +69,9 @@ public interface IConventionProperty : IProperty, IConventionPropertyBase
ValueGenerated? SetValueGenerated(ValueGenerated? valueGenerated, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetValueGeneratedConfigurationSource();
///
@@ -90,9 +90,9 @@ public interface IConventionProperty : IProperty, IConventionPropertyBase
bool? SetIsConcurrencyToken(bool? concurrencyToken, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetIsConcurrencyTokenConfigurationSource();
///
diff --git a/src/EFCore/Metadata/IConventionPropertyBase.cs b/src/EFCore/Metadata/IConventionPropertyBase.cs
index 96eacc7fa8a..ca730594b22 100644
--- a/src/EFCore/Metadata/IConventionPropertyBase.cs
+++ b/src/EFCore/Metadata/IConventionPropertyBase.cs
@@ -16,10 +16,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionPropertyBase : IPropertyBase, IConventionAnnotatable
+ public interface IConventionPropertyBase : IReadOnlyPropertyBase, IConventionAnnotatable
{
///
/// Gets the type that this property belongs to.
@@ -91,9 +91,9 @@ void SetField([CanBeNull] FieldInfo? fieldInfo, bool fromDataAnnotation = false)
.SetField(fieldName, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetFieldInfoConfigurationSource();
}
}
diff --git a/src/EFCore/Metadata/IConventionServiceProperty.cs b/src/EFCore/Metadata/IConventionServiceProperty.cs
index 18d839d004a..38a66dc9b42 100644
--- a/src/EFCore/Metadata/IConventionServiceProperty.cs
+++ b/src/EFCore/Metadata/IConventionServiceProperty.cs
@@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// A in the Entity Framework model that represents an
+ /// A in the Entity Framework model that represents an
/// injected service from the .
///
///
@@ -19,7 +19,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionServiceProperty : IServiceProperty, IConventionPropertyBase
+ public interface IConventionServiceProperty : IReadOnlyServiceProperty, IConventionPropertyBase
{
///
/// Gets the builder that can be used to configure this service property.
@@ -41,9 +41,9 @@ public interface IConventionServiceProperty : IServiceProperty, IConventionPrope
ServiceParameterBinding? SetParameterBinding([CanBeNull] ServiceParameterBinding? parameterBinding, bool fromDataAnnotation = false);
///
- /// Returns the configuration source for .
+ /// Returns the configuration source for .
///
- /// The configuration source for .
+ /// The configuration source for .
ConfigurationSource? GetParameterBindingConfigurationSource();
}
}
diff --git a/src/EFCore/Metadata/IConventionSkipNavigation.cs b/src/EFCore/Metadata/IConventionSkipNavigation.cs
index d7a154304e1..e08e1b2b1e0 100644
--- a/src/EFCore/Metadata/IConventionSkipNavigation.cs
+++ b/src/EFCore/Metadata/IConventionSkipNavigation.cs
@@ -20,7 +20,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigationBase
+ public interface IConventionSkipNavigation : IReadOnlySkipNavigation, IConventionNavigationBase
{
///
/// Gets the builder that can be used to configure this property.
@@ -34,7 +34,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigat
new IConventionEntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => (IConventionEntityType)((INavigationBase)this).DeclaringEntityType;
+ get => (IConventionEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
}
///
@@ -43,7 +43,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigat
new IConventionEntityType TargetEntityType
{
[DebuggerStepThrough]
- get => (IConventionEntityType)((INavigationBase)this).TargetEntityType;
+ get => (IConventionEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
@@ -52,7 +52,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigat
new IConventionEntityType? JoinEntityType
{
[DebuggerStepThrough]
- get => (IConventionEntityType?)((ISkipNavigation)this).JoinEntityType;
+ get => (IConventionEntityType?)((IReadOnlySkipNavigation)this).JoinEntityType;
}
///
@@ -61,7 +61,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigat
new IConventionForeignKey? ForeignKey
{
[DebuggerStepThrough]
- get => (IConventionForeignKey?)((ISkipNavigation)this).ForeignKey;
+ get => (IConventionForeignKey?)((IReadOnlySkipNavigation)this).ForeignKey;
}
///
@@ -86,7 +86,7 @@ public interface IConventionSkipNavigation : ISkipNavigation, IConventionNavigat
new IConventionSkipNavigation? Inverse
{
[DebuggerStepThrough]
- get => (IConventionSkipNavigation?)((ISkipNavigation)this).Inverse;
+ get => (IConventionSkipNavigation?)((IReadOnlySkipNavigation)this).Inverse;
}
///
diff --git a/src/EFCore/Metadata/IConventionTypeBase.cs b/src/EFCore/Metadata/IConventionTypeBase.cs
index 1aa7923328c..0daca1a9c12 100644
--- a/src/EFCore/Metadata/IConventionTypeBase.cs
+++ b/src/EFCore/Metadata/IConventionTypeBase.cs
@@ -14,10 +14,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IConventionTypeBase : ITypeBase, IConventionAnnotatable
+ public interface IConventionTypeBase : IReadOnlyTypeBase, IConventionAnnotatable
{
///
/// Gets the model that this type belongs to.
diff --git a/src/EFCore/Metadata/IEntityType.cs b/src/EFCore/Metadata/IEntityType.cs
index dd85398ed9d..ea11a369fde 100644
--- a/src/EFCore/Metadata/IEntityType.cs
+++ b/src/EFCore/Metadata/IEntityType.cs
@@ -1,7 +1,6 @@
// 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.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -13,39 +12,21 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents an entity type in an .
+ /// Represents an entity type in a model.
///
- public interface IEntityType : ITypeBase
+ public interface IEntityType : IReadOnlyEntityType, ITypeBase
{
///
- /// Gets the base type of this entity type. Returns if this is not a derived type in an inheritance hierarchy.
+ /// Gets the base type of this entity type. Returns if this is not a derived type in an inheritance
+ /// hierarchy.
///
- IEntityType? BaseType { get; }
-
- ///
- /// Gets the name of the defining navigation.
- ///
- [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
- string? DefiningNavigationName => null;
-
- ///
- /// Gets the defining entity type.
- ///
- [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
- IEntityType? DefiningEntityType => null;
-
- ///
- /// Gets a value indicating whether this entity type has a defining navigation.
- ///
- /// if this entity type has a defining navigation.
- [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
- public bool HasDefiningNavigation() => HasSharedClrType;
+ new IEntityType? BaseType { get; }
///
/// Gets primary key for this entity type. Returns if no primary key is defined.
///
/// The primary key, or if none is defined.
- IKey? FindPrimaryKey();
+ new IKey? FindPrimaryKey();
///
/// Gets the primary or alternate key that is defined on the given properties.
@@ -53,13 +34,13 @@ public interface IEntityType : ITypeBase
///
/// The properties that make up the key.
/// The key, or if none is defined.
- IKey? FindKey([NotNull] IReadOnlyList properties);
+ new IKey? FindKey([NotNull] IReadOnlyList properties);
///
/// Gets the primary and alternate keys for this entity type.
///
/// The primary and alternate keys.
- IEnumerable GetKeys();
+ new IEnumerable GetKeys();
///
/// Gets the foreign key for the given properties that points to a given primary or alternate key.
@@ -73,48 +54,40 @@ public interface IEntityType : ITypeBase
/// base type of the hierarchy).
///
/// The foreign key, or if none is defined.
- IForeignKey? FindForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType);
+ new IForeignKey? FindForeignKey(
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType);
///
/// Gets the foreign keys defined on this entity type.
///
/// The foreign keys defined on this entity type.
- IEnumerable GetForeignKeys();
+ new IEnumerable GetForeignKeys();
///
/// Gets a skip navigation property on this entity type. Returns if no navigation property is found.
///
/// The navigation property on the entity class.
/// The navigation property, or if none is found.
- ISkipNavigation? FindSkipNavigation([NotNull] MemberInfo memberInfo)
- => FindSkipNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
+ new ISkipNavigation? FindSkipNavigation([NotNull] MemberInfo memberInfo)
+ => (ISkipNavigation?)((IReadOnlyEntityType)this).FindSkipNavigation(memberInfo);
///
/// Gets a skip navigation property on this entity type. Returns if no skip navigation property is found.
///
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
- ISkipNavigation? FindSkipNavigation([NotNull] string name);
+ new ISkipNavigation? FindSkipNavigation([NotNull] string name);
///
- ///
- /// Gets a skip navigation property on this entity type.
- ///
- ///
- /// Does not return skip navigation properties defined on a base type.
- /// Returns if no skip navigation property is found.
- ///
+ /// Gets a skip navigation property on this entity type. Does not return skip navigation properties defined on a base type.
+ /// Returns if no skip navigation property is found.
///
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
- ISkipNavigation? FindDeclaredSkipNavigation([NotNull] string name)
- {
- var navigation = FindSkipNavigation(name);
- return navigation?.DeclaringEntityType == this ? navigation : null;
- }
+ new ISkipNavigation? FindDeclaredSkipNavigation([NotNull] string name)
+ => (ISkipNavigation?)((IReadOnlyEntityType)this).FindDeclaredSkipNavigation(name);
///
///
@@ -127,14 +100,14 @@ public interface IEntityType : ITypeBase
///
///
/// Declared foreign keys.
- IEnumerable GetDeclaredSkipNavigations()
- => GetSkipNavigations().Where(n => n.DeclaringEntityType == this);
+ new IEnumerable GetDeclaredSkipNavigations()
+ => ((IReadOnlyEntityType)this).GetDeclaredSkipNavigations().Cast();
///
/// Gets the skip navigation properties on this entity type.
///
- /// All skip navigation properties on this entity type.
- IEnumerable GetSkipNavigations();
+ /// The skip navigation properties on this entity type.
+ new IEnumerable GetSkipNavigations();
///
///
@@ -146,20 +119,20 @@ IEnumerable GetDeclaredSkipNavigations()
///
/// The properties to find the index on.
/// The index, or if none is found.
- IIndex? FindIndex([NotNull] IReadOnlyList properties);
+ new IIndex? FindIndex([NotNull] IReadOnlyList properties);
///
/// Gets the index with the given name. Returns if no such index exists.
///
- /// The name of the index to find.
+ /// The name of the index.
/// The index, or if none is found.
- IIndex? FindIndex([NotNull] string name);
+ new IIndex? FindIndex([NotNull] string name);
///
/// Gets the indexes defined on this entity type.
///
/// The indexes defined on this entity type.
- IEnumerable GetIndexes();
+ new IEnumerable GetIndexes();
///
///
@@ -167,12 +140,12 @@ IEnumerable GetDeclaredSkipNavigations()
///
///
/// This API only finds scalar properties and does not find navigation properties. Use
- /// to find a navigation property.
+ /// to find a navigation property.
///
///
/// The name of the property.
/// The property, or if none is found.
- IProperty? FindProperty([NotNull] string name);
+ new IProperty? FindProperty([NotNull] string name);
///
///
@@ -180,11 +153,24 @@ IEnumerable GetDeclaredSkipNavigations()
///
///
/// This API only returns scalar properties and does not return navigation properties. Use
- /// to get navigation properties.
+ /// to get navigation properties.
///
///
/// The properties defined on this entity type.
- IEnumerable GetProperties();
+ new IEnumerable GetProperties();
+
+ ///
+ /// Returns the properties contained in foreign keys.
+ ///
+ /// The properties contained in foreign keys.
+ IEnumerable GetForeignKeyProperties();
+
+ ///
+ /// Returns the properties that need a value to be generated when the entity entry transitions to the
+ /// state.
+ ///
+ /// The properties that need a value to be generated on add.
+ IEnumerable GetValueGeneratingProperties();
///
///
@@ -197,7 +183,7 @@ IEnumerable GetDeclaredSkipNavigations()
///
/// The name of the property.
/// The service property, or if none is found.
- IServiceProperty? FindServiceProperty([NotNull] string name);
+ new IServiceProperty? FindServiceProperty([NotNull] string name);
///
///
@@ -208,6 +194,331 @@ IEnumerable GetDeclaredSkipNavigations()
///
///
/// The service properties defined on this entity type.
- IEnumerable GetServiceProperties();
+ new IEnumerable GetServiceProperties();
+
+ ///
+ /// Returns all the derived types of the given , including the type itself,
+ /// which are not .
+ ///
+ /// Non-abstract, derived types.
+ IEnumerable GetConcreteDerivedTypesInclusive()
+ => ((IReadOnlyEntityType)this).GetConcreteDerivedTypesInclusive().Cast();
+
+ ///
+ /// Returns the that will be used for storing a discriminator value.
+ ///
+ IProperty? GetDiscriminatorProperty()
+ => (IProperty?)((IReadOnlyEntityType)this).GetDiscriminatorProperty();
+
+ ///
+ /// Gets the root base type for a given entity type.
+ ///
+ ///
+ /// The root base type. If the given entity type is not a derived type, then the same entity type is returned.
+ ///
+ IEntityType GetRootType()
+ => (IEntityType)((IReadOnlyEntityType)this).GetRootType();
+
+ ///
+ /// Gets all types in the model from which a given entity type derives, starting with the root.
+ ///
+ /// The base types.
+ IEnumerable GetAllBaseTypes()
+ => GetAllBaseTypesAscending().Reverse();
+
+ ///
+ /// Returns all base types of the given entity type, including the type itself, top to bottom.
+ ///
+ /// The base types.
+ IEnumerable GetAllBaseTypesInclusive()
+ => GetAllBaseTypesInclusiveAscending().Reverse();
+
+ ///
+ /// Gets all types in the model from which a given entity type derives, starting with the closest one.
+ ///
+ /// The base types.
+ IEnumerable GetAllBaseTypesAscending()
+ => GetAllBaseTypesInclusiveAscending().Skip(1);
+
+ ///
+ /// Returns all base types of the given entity type, including the type itself, bottom to top.
+ ///
+ /// The base types.
+ IEnumerable GetAllBaseTypesInclusiveAscending()
+ => ((IReadOnlyEntityType)this).GetAllBaseTypesInclusiveAscending().Cast();
+
+ ///
+ /// Gets all types in the model that derive from a given entity type.
+ ///
+ /// The derived types.
+ IEnumerable GetDerivedTypes()
+ => ((IReadOnlyEntityType)this).GetDerivedTypes().Cast();
+
+ ///
+ /// Returns all derived types of the given , including the type itself.
+ ///
+ /// Derived types.
+ IEnumerable GetDerivedTypesInclusive()
+ => ((IReadOnlyEntityType)this).GetDerivedTypesInclusive().Cast();
+
+ ///
+ /// Gets all types in the model that directly derive from a given entity type.
+ ///
+ /// The derived types.
+ IEnumerable GetDirectlyDerivedTypes();
+
+ ///
+ ///
+ /// Gets all keys declared on the given .
+ ///
+ ///
+ /// This method does not return keys declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same key more than once.
+ /// Use to also return keys declared on base types.
+ ///
+ ///
+ /// Declared keys.
+ IEnumerable GetDeclaredKeys();
+
+ ///
+ /// Gets the primary or alternate key that is defined on the given property. Returns if no key is defined
+ /// for the given property.
+ /// ///
+ /// The property that the key is defined on.
+ /// The key, or null if none is defined.
+ IKey? FindKey([NotNull] IReadOnlyProperty property) => FindKey(new[] { property });
+
+ ///
+ ///
+ /// Gets all non-navigation properties declared on the given .
+ ///
+ ///
+ /// This method does not return properties declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same property more than once.
+ /// Use to also return properties declared on base types.
+ ///
+ ///
+ /// Declared non-navigation properties.
+ IEnumerable GetDeclaredProperties();
+
+ ///
+ ///
+ /// Gets all navigation properties declared on the given .
+ ///
+ ///
+ /// This method does not return navigation properties declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same navigation property more than once.
+ /// Use to also return navigation properties declared on base types.
+ ///
+ ///
+ /// Declared navigation properties.
+ IEnumerable GetDeclaredNavigations();
+
+ ///
+ ///
+ /// Gets all service properties declared on the given .
+ ///
+ ///
+ /// This method does not return properties declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same property more than once.
+ /// Use to also return properties declared on base types.
+ ///
+ ///
+ /// Declared service properties.
+ IEnumerable GetDeclaredServiceProperties();
+
+ ///
+ ///
+ /// Gets all indexes declared on the given .
+ ///
+ ///
+ /// This method does not return indexes declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same index more than once.
+ /// Use to also return indexes declared on base types.
+ ///
+ ///
+ /// Declared indexes.
+ IEnumerable GetDeclaredIndexes();
+
+ ///
+ ///
+ /// Gets all indexes declared on the types derived from the given .
+ ///
+ ///
+ /// Derived indexes.
+ IEnumerable GetDerivedIndexes();
+
+ ///
+ ///
+ /// Gets all foreign keys declared on the given .
+ ///
+ ///
+ /// This method does not return foreign keys declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same foreign key more than once.
+ /// Use to also return foreign keys declared on base types.
+ ///
+ ///
+ /// Declared foreign keys.
+ IEnumerable GetDeclaredForeignKeys();
+
+ ///
+ ///
+ /// Gets all foreign keys declared on the types derived from the given .
+ ///
+ ///
+ /// Derived foreign keys.
+ IEnumerable GetDerivedForeignKeys();
+
+ ///
+ /// Gets the foreign keys defined on the given property. Only foreign keys that are defined on exactly the specified
+ /// property are returned. Composite foreign keys that include the specified property are not returned.
+ ///
+ /// The property to find the foreign keys on.
+ /// The foreign keys.
+ IEnumerable FindForeignKeys([NotNull] IReadOnlyProperty property)
+ => FindForeignKeys(new[] { property });
+
+ ///
+ /// Gets the foreign keys defined on the given properties. Only foreign keys that are defined on exactly the specified
+ /// set of properties are returned.
+ ///
+ /// The properties to find the foreign keys on.
+ /// The foreign keys.
+ IEnumerable FindForeignKeys([NotNull] IReadOnlyList properties);
+
+ ///
+ /// Gets the foreign key for the given properties that points to a given primary or alternate key. Returns
+ /// if no foreign key is found.
+ ///
+ /// The property that the foreign key is defined on.
+ /// The primary or alternate key that is referenced.
+ ///
+ /// The entity type that the relationship targets. This may be different from the type that
+ /// is defined on when the relationship targets a derived type in an inheritance hierarchy (since the key is defined on the
+ /// base type of the hierarchy).
+ ///
+ /// The foreign key, or if none is defined.
+ IForeignKey? FindForeignKey(
+ [NotNull] IReadOnlyProperty property,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
+ => FindForeignKey(new[] { property }, principalKey, principalEntityType);
+
+ ///
+ /// Gets the foreign keys declared on the given using the given properties.
+ ///
+ /// The properties to find the foreign keys on.
+ /// Declared foreign keys.
+ IEnumerable FindDeclaredForeignKeys([NotNull] IReadOnlyList properties);
+
+ ///
+ /// Gets all foreign keys that target a given entity type (i.e. foreign keys where the given entity type
+ /// or a type it's derived from is the principal).
+ ///
+ /// The foreign keys that reference the given entity type.
+ IEnumerable GetReferencingForeignKeys();
+
+ ///
+ /// Gets all foreign keys that target a given entity type (i.e. foreign keys where the given entity type
+ /// is the principal).
+ ///
+ /// The foreign keys that reference the given entity type.
+ IEnumerable GetDeclaredReferencingForeignKeys();
+
+ ///
+ /// Returns the relationship to the owner if this is an owned type or otherwise.
+ ///
+ /// The relationship to the owner if this is an owned type or otherwise.
+ IForeignKey? FindOwnership()
+ => (IForeignKey?)((IReadOnlyEntityType)this).FindOwnership();
+
+ ///
+ /// Gets a navigation property on the given entity type. Returns if no navigation property is found.
+ ///
+ /// The navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ INavigation? FindNavigation([NotNull] MemberInfo memberInfo)
+ => FindNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
+
+ ///
+ /// Gets a navigation property on the given entity type. Returns if no navigation property is found.
+ ///
+ /// The name of the navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ INavigation? FindNavigation([NotNull] string name)
+ => (INavigation?)((IReadOnlyEntityType)this).FindNavigation(name);
+
+ ///
+ /// Gets a navigation property on the given entity type. Does not return navigation properties defined on a base type.
+ /// Returns if no navigation property is found.
+ ///
+ /// The name of the navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ INavigation? FindDeclaredNavigation([NotNull] string name);
+
+ ///
+ /// Gets all navigation properties on the given entity type.
+ ///
+ /// All navigation properties on the given entity type.
+ IEnumerable GetNavigations()
+ => ((IReadOnlyEntityType)this).GetNavigations().Cast();
+
+ ///
+ ///
+ /// Gets a property on the given entity type. Returns if no property is found.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties. Use
+ /// to find a navigation property.
+ ///
+ ///
+ /// The property on the entity class.
+ /// The property, or if none is found.
+ IProperty? FindProperty([NotNull] MemberInfo memberInfo)
+ => (IProperty?)((IReadOnlyEntityType)this).FindProperty(memberInfo);
+
+ ///
+ ///
+ /// Finds matching properties on the given entity type. Returns if any property is not found.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties.
+ ///
+ ///
+ /// The property names.
+ /// The properties, or if any property is not found.
+ IReadOnlyList? FindProperties(
+ [NotNull] IReadOnlyList propertyNames)
+ => (IReadOnlyList?)((IReadOnlyEntityType)this).FindProperties(propertyNames);
+
+ ///
+ ///
+ /// Gets a property with the given name.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties. Use
+ /// to find a navigation property.
+ ///
+ ///
+ /// The property name.
+ /// The property, or if none is found.
+ IProperty GetProperty([NotNull] string name)
+ => (IProperty)((IReadOnlyEntityType)this).GetProperty(name);
+
+ ///
+ /// Finds a property declared on the type with the given name.
+ /// Does not return properties defined on a base type.
+ ///
+ /// The property name.
+ /// The property, or if none is found.
+ IProperty? FindDeclaredProperty([NotNull] string name);
+
+ ///
+ /// Gets the index defined on the given property. Returns null if no index is defined.
+ ///
+ /// The property to find the index on.
+ /// The index, or null if none is found.
+ IIndex? FindIndex([NotNull] IReadOnlyProperty property)
+ => FindIndex(new[] { property });
}
}
diff --git a/src/EFCore/Metadata/IForeignKey.cs b/src/EFCore/Metadata/IForeignKey.cs
index 9db25bc2cc8..23694968eeb 100644
--- a/src/EFCore/Metadata/IForeignKey.cs
+++ b/src/EFCore/Metadata/IForeignKey.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
#nullable enable
@@ -10,80 +11,70 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a relationship where a foreign key property(s) in a dependent entity type
- /// reference a corresponding primary or alternate key in a principal entity type.
+ /// Represents a relationship where a foreign key composed of properties on the dependent entity type
+ /// references a corresponding primary or alternate key on the principal entity type.
///
- public interface IForeignKey : IAnnotatable
+ public interface IForeignKey : IReadOnlyForeignKey, IAnnotatable
{
- ///
- /// Gets the dependent entity type. This may be different from the type that
- /// are defined on when the relationship is defined a derived type in an inheritance hierarchy (since the properties
- /// may be defined on a base type).
- ///
- IEntityType DeclaringEntityType { get; }
-
///
/// Gets the foreign key properties in the dependent entity.
///
- IReadOnlyList Properties { get; }
-
- ///
- /// Gets the principal entity type that this relationship targets. This may be different from the type that
- /// is defined on when the relationship targets a derived type in an inheritance
- /// hierarchy (since the key is defined on the base type of the hierarchy).
- ///
- IEntityType PrincipalEntityType { get; }
+ new IReadOnlyList Properties { get; }
///
/// Gets the primary or alternate key that the relationship targets.
///
- IKey PrincipalKey { get; }
+ new IKey PrincipalKey { get; }
///
- /// Gets the navigation property on the dependent entity type that points to the principal entity.
- ///
- INavigation? DependentToPrincipal { get; }
-
- ///
- /// Gets the navigation property on the principal entity type that points to the dependent entity.
+ /// Gets the dependent entity type. This may be different from the type that
+ /// are defined on when the relationship is defined a derived type in an inheritance hierarchy (since the properties
+ /// may be defined on a base type).
///
- INavigation? PrincipalToDependent { get; }
+ new IEntityType DeclaringEntityType { get; }
///
- /// Gets a value indicating whether the values assigned to the foreign key properties are unique.
+ /// Gets the principal entity type that this relationship targets. This may be different from the type that
+ /// is defined on when the relationship targets a derived type in an inheritance
+ /// hierarchy (since the key is defined on the base type of the hierarchy).
///
- bool IsUnique { get; }
+ new IEntityType PrincipalEntityType { get; }
///
- /// Gets a value indicating whether the principal entity is required.
- /// If , the dependent entity must always be assigned to a valid principal entity.
+ /// Gets the navigation property on the dependent entity type that points to the principal entity.
///
- bool IsRequired { get; }
+ new INavigation? DependentToPrincipal { get; }
///
- /// Gets a value indicating whether the dependent entity is required.
- /// If , the principal entity must always have a valid dependent entity assigned.
+ /// Gets the navigation property on the principal entity type that points to the dependent entity.
///
- bool IsRequiredDependent { get; }
+ new INavigation? PrincipalToDependent { get; }
///
- /// Gets or sets a value indicating whether this relationship defines an ownership.
- /// If , the dependent entity must always be accessed via the navigation from the principal entity.
+ /// Gets all skip navigations using this foreign key.
///
- bool IsOwnership { get; }
+ /// The skip navigations using this foreign key.
+ new IEnumerable GetReferencingSkipNavigations()
+ => ((IReadOnlyForeignKey)this).GetReferencingSkipNavigations().Cast();
///
- /// Gets a value indicating how a delete operation is applied to dependent entities in the relationship when the
- /// principal is deleted or the relationship is severed.
+ /// Gets the entity type related to the given one.
///
- DeleteBehavior DeleteBehavior { get; }
+ /// One of the entity types related by the foreign key.
+ /// The entity type related to the given one.
+ IEntityType GetRelatedEntityType([NotNull] IEntityType entityType)
+ => (IEntityType)((IReadOnlyForeignKey)this).GetRelatedEntityType(entityType);
///
- /// Gets the skip navigations using this foreign key.
+ /// Returns a navigation associated with this foreign key.
///
- /// The skip navigations using this foreign key.
- IEnumerable GetReferencingSkipNavigations()
- => PrincipalEntityType.GetSkipNavigations().Where(n => !n.IsOnDependent && n.ForeignKey == this)
- .Concat(DeclaringEntityType.GetSkipNavigations().Where(n => n.IsOnDependent && n.ForeignKey == this));
+ ///
+ /// A value indicating whether the navigation is on the dependent type pointing to the principal type.
+ ///
+ ///
+ /// A navigation associated with this foreign key or .
+ ///
+ INavigation? GetNavigation(bool pointsToPrincipal)
+ => pointsToPrincipal ? DependentToPrincipal : PrincipalToDependent;
}
}
diff --git a/src/EFCore/Metadata/IIndex.cs b/src/EFCore/Metadata/IIndex.cs
index 453cc2daf4f..5bf0739353f 100644
--- a/src/EFCore/Metadata/IIndex.cs
+++ b/src/EFCore/Metadata/IIndex.cs
@@ -11,28 +11,18 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents an index on a set of properties.
///
- public interface IIndex : IAnnotatable
+ public interface IIndex : IReadOnlyIndex, IAnnotatable
{
///
/// Gets the properties that this index is defined on.
///
- IReadOnlyList Properties { get; }
-
- ///
- /// Gets the name of this index.
- ///
- string? Name { get; }
-
- ///
- /// Gets a value indicating whether the values assigned to the indexed properties are unique.
- ///
- bool IsUnique { get; }
+ new IReadOnlyList Properties { get; }
///
/// Gets the entity type the index is defined on. This may be different from the type that
/// are defined on when the index is defined a derived type in an inheritance hierarchy (since the properties
/// may be defined on a base type).
///
- IEntityType DeclaringEntityType { get; }
+ new IEntityType DeclaringEntityType { get; }
}
}
diff --git a/src/EFCore/Metadata/IKey.cs b/src/EFCore/Metadata/IKey.cs
index a2a7a1ee832..de28742c03b 100644
--- a/src/EFCore/Metadata/IKey.cs
+++ b/src/EFCore/Metadata/IKey.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 System.Linq;
using Microsoft.EntityFrameworkCore.Infrastructure;
#nullable enable
@@ -9,20 +10,27 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a primary or alternate key on an entity.
+ /// Represents a primary or alternate key on an entity type.
///
- public interface IKey : IAnnotatable
+ public interface IKey : IReadOnlyKey, IAnnotatable
{
///
/// Gets the properties that make up the key.
///
- IReadOnlyList Properties { get; }
+ new IReadOnlyList Properties { get; }
///
/// Gets the entity type the key is defined on. This may be different from the type that
/// are defined on when the key is defined a derived type in an inheritance hierarchy (since the properties
/// may be defined on a base type).
///
- IEntityType DeclaringEntityType { get; }
+ new IEntityType DeclaringEntityType { get; }
+
+ ///
+ /// Gets all foreign keys that target a given primary or alternate key.
+ ///
+ /// The foreign keys that reference the given key.
+ IEnumerable GetReferencingForeignKeys()
+ => ((IReadOnlyKey)this).GetReferencingForeignKeys().Cast();
}
}
diff --git a/src/EFCore/Metadata/IModel.cs b/src/EFCore/Metadata/IModel.cs
index 35fdb85e01f..0e7190a9dcd 100644
--- a/src/EFCore/Metadata/IModel.cs
+++ b/src/EFCore/Metadata/IModel.cs
@@ -1,10 +1,14 @@
// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
#nullable enable
@@ -25,36 +29,54 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// The implementation does not need to be thread-safe.
///
///
- public interface IModel : IAnnotatable
+ public interface IModel : IReadOnlyModel, IAnnotatable
{
///
- /// Gets all entity types defined in the model.
- ///
- /// All entity types defined in the model.
- IEnumerable GetEntityTypes();
-
- ///
- /// Gets the entity type with the given name. Returns if no entity type with the given name is found
+ /// Gets the entity with the given name. Returns if no entity type with the given name is found
/// or the given CLR type is being used by shared type entity type
/// or the entity type has a defining navigation.
///
/// The name of the entity type to find.
- /// The entity type, or if none are found.
- IEntityType? FindEntityType([NotNull] string name);
+ /// The entity type, or if none is found.
+ new IEntityType? FindEntityType([NotNull] string name);
///
- /// Gets the entity type for the given base name, defining navigation name
- /// and the defining entity type. Returns if no matching entity type is found.
+ /// Gets the entity type for the given name, defining navigation name
+ /// and the defining entity type. Returns if no matching entity type is found.
///
/// The name of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
IEntityType? FindEntityType(
[NotNull] string name,
[NotNull] string definingNavigationName,
[NotNull] IEntityType definingEntityType);
+ ///
+ /// Gets the entity that maps the given entity class, where the class may be a proxy derived from the
+ /// actual entity type. Returns if no entity type with the given CLR type is found
+ /// or the given CLR type is being used by shared type entity type
+ /// or the entity type has a defining navigation.
+ ///
+ /// The type to find the corresponding entity type for.
+ /// The entity type, or if none is found.
+ IEntityType? FindRuntimeEntityType([NotNull] Type type)
+ {
+ Check.NotNull(type, nameof(type));
+
+ return FindEntityType(type)
+ ?? (type.BaseType == null
+ ? null
+ : FindEntityType(type.BaseType));
+ }
+
+ ///
+ /// Gets all entity types defined in the model.
+ ///
+ /// All entity types defined in the model.
+ new IEnumerable GetEntityTypes();
+
///
/// The runtime service dependencies.
///
@@ -77,5 +99,48 @@ bool SetModelDependencies([NotNull] SingletonModelDependencies modelDependencies
return true;
}
+
+ ///
+ /// Gets the entity that maps the given entity class. Returns if no entity type with
+ /// the given CLR type is found or the given CLR type is being used by shared type entity type
+ /// or the entity type has a defining navigation.
+ ///
+ /// The type to find the corresponding entity type for.
+ /// The entity type, or if none is found.
+ IEntityType? FindEntityType([NotNull] Type type);
+
+ ///
+ /// Gets the entity type for the given name, defining navigation name
+ /// and the defining entity type. Returns if no matching entity type is found.
+ ///
+ /// The type of the entity type to find.
+ /// The defining navigation of the entity type to find.
+ /// The defining entity type of the entity type to find.
+ /// The entity type, or if none is found.
+ IEntityType? FindEntityType(
+ [NotNull] Type type,
+ [NotNull] string definingNavigationName,
+ [NotNull] IEntityType definingEntityType)
+ => (IEntityType?)((IReadOnlyModel)this).FindEntityType(type, definingNavigationName, definingEntityType);
+
+ ///
+ /// Gets the entity types matching the given type.
+ ///
+ /// The type of the entity type to find.
+ /// The entity types found.
+ [DebuggerStepThrough]
+ IEnumerable GetEntityTypes([NotNull] Type type);
+
+ ///
+ /// Returns the entity types corresponding to the least derived types from the given.
+ ///
+ /// The base type.
+ /// An optional condition for filtering entity types.
+ /// List of entity types corresponding to the least derived types from the given.
+ IEnumerable FindLeastDerivedEntityTypes(
+ [NotNull] Type type,
+ [CanBeNull] Func? condition = null)
+ => ((IReadOnlyModel)this).FindLeastDerivedEntityTypes(type, condition == null ? null : t => condition((IEntityType)t))
+ .Cast();
}
}
diff --git a/src/EFCore/Metadata/IMutableAnnotatable.cs b/src/EFCore/Metadata/IMutableAnnotatable.cs
index 65f081dcba3..1951cd37750 100644
--- a/src/EFCore/Metadata/IMutableAnnotatable.cs
+++ b/src/EFCore/Metadata/IMutableAnnotatable.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// not used in application code.
///
///
- public interface IMutableAnnotatable : IAnnotatable
+ public interface IMutableAnnotatable : IReadOnlyAnnotatable
{
///
/// Gets or sets the value of the annotation with the given name.
diff --git a/src/EFCore/Metadata/IMutableEntityType.cs b/src/EFCore/Metadata/IMutableEntityType.cs
index b7c6511ced2..14c7045abba 100644
--- a/src/EFCore/Metadata/IMutableEntityType.cs
+++ b/src/EFCore/Metadata/IMutableEntityType.cs
@@ -13,14 +13,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// Represents an entity in an .
+ /// Represents an entity type in an .
///
///
/// 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 IMutableEntityType : IEntityType, IMutableTypeBase
+ public interface IMutableEntityType : IReadOnlyEntityType, IMutableTypeBase
{
///
/// Gets the model this entity belongs to.
@@ -79,7 +79,7 @@ public interface IMutableEntityType : IEntityType, IMutableTypeBase
///
/// The properties that make up the key.
/// The key, or if none is defined.
- new IMutableKey? FindKey([NotNull] IReadOnlyList properties);
+ new IMutableKey? FindKey([NotNull] IReadOnlyList properties);
///
/// Gets the primary and alternate keys for this entity type.
@@ -123,9 +123,9 @@ IMutableForeignKey AddForeignKey(
///
/// The foreign key, or if none is defined.
new IMutableForeignKey? FindForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType);
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType);
///
/// Gets the foreign keys defined on this entity type.
@@ -171,7 +171,7 @@ IMutableSkipNavigation AddSkipNavigation(
/// The navigation property on the entity class.
/// The navigation property, or if none is found.
new IMutableSkipNavigation? FindSkipNavigation([NotNull] MemberInfo memberInfo)
- => (IMutableSkipNavigation?)((IEntityType)this).FindSkipNavigation(memberInfo);
+ => (IMutableSkipNavigation?)((IReadOnlyEntityType)this).FindSkipNavigation(memberInfo);
///
/// Gets a skip navigation property on this entity type. Returns if no skip navigation property is found.
@@ -187,7 +187,7 @@ IMutableSkipNavigation AddSkipNavigation(
/// The name of the navigation property on the entity class.
/// The navigation property, or if none is found.
new IMutableSkipNavigation? FindDeclaredSkipNavigation([NotNull] string name)
- => (IMutableSkipNavigation?)((IEntityType)this).FindDeclaredSkipNavigation(name);
+ => (IMutableSkipNavigation?)((IReadOnlyEntityType)this).FindDeclaredSkipNavigation(name);
///
///
@@ -201,7 +201,7 @@ IMutableSkipNavigation AddSkipNavigation(
///
/// Declared foreign keys.
new IEnumerable GetDeclaredSkipNavigations()
- => ((IEntityType)this).GetDeclaredSkipNavigations().Cast();
+ => ((IReadOnlyEntityType)this).GetDeclaredSkipNavigations().Cast();
///
/// Gets the skip navigation properties on this entity type.
@@ -243,7 +243,7 @@ IMutableIndex AddIndex(
///
/// The properties to find the index on.
/// The index, or if none is found.
- new IMutableIndex? FindIndex([NotNull] IReadOnlyList properties);
+ new IMutableIndex? FindIndex([NotNull] IReadOnlyList properties);
///
/// Gets the index with the given name. Returns if no such index exists.
diff --git a/src/EFCore/Metadata/IMutableForeignKey.cs b/src/EFCore/Metadata/IMutableForeignKey.cs
index bc674a0250e..ce7f005ea23 100644
--- a/src/EFCore/Metadata/IMutableForeignKey.cs
+++ b/src/EFCore/Metadata/IMutableForeignKey.cs
@@ -21,7 +21,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableForeignKey : IForeignKey, IMutableAnnotatable
+ public interface IMutableForeignKey : IReadOnlyForeignKey, IMutableAnnotatable
{
///
/// Gets the foreign key properties in the dependent entity.
@@ -186,6 +186,6 @@ public interface IMutableForeignKey : IForeignKey, IMutableAnnotatable
///
/// The skip navigations using this foreign key.
new IEnumerable GetReferencingSkipNavigations()
- => ((IForeignKey)this).GetReferencingSkipNavigations().Cast();
+ => ((IReadOnlyForeignKey)this).GetReferencingSkipNavigations().Cast();
}
}
diff --git a/src/EFCore/Metadata/IMutableIndex.cs b/src/EFCore/Metadata/IMutableIndex.cs
index bfce47e9129..2ea68fa1316 100644
--- a/src/EFCore/Metadata/IMutableIndex.cs
+++ b/src/EFCore/Metadata/IMutableIndex.cs
@@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableIndex : IIndex, IMutableAnnotatable
+ public interface IMutableIndex : IReadOnlyIndex, IMutableAnnotatable
{
///
/// Gets or sets a value indicating whether the values assigned to the indexed properties are unique.
diff --git a/src/EFCore/Metadata/IMutableKey.cs b/src/EFCore/Metadata/IMutableKey.cs
index e5f7254ed9c..51273eea325 100644
--- a/src/EFCore/Metadata/IMutableKey.cs
+++ b/src/EFCore/Metadata/IMutableKey.cs
@@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableKey : IMutableAnnotatable, IKey
+ public interface IMutableKey : IMutableAnnotatable, IReadOnlyKey
{
///
/// Gets the properties that make up the key.
diff --git a/src/EFCore/Metadata/IMutableModel.cs b/src/EFCore/Metadata/IMutableModel.cs
index 65e42720164..beb0b1cf422 100644
--- a/src/EFCore/Metadata/IMutableModel.cs
+++ b/src/EFCore/Metadata/IMutableModel.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableModel : IModel, IMutableAnnotatable
+ public interface IMutableModel : IReadOnlyModel, IMutableAnnotatable
{
///
///
@@ -100,7 +100,7 @@ IMutableEntityType AddEntityType(
/// or the entity type has a defining navigation.
///
/// The name of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
new IMutableEntityType? FindEntityType([NotNull] string name);
///
@@ -110,7 +110,7 @@ IMutableEntityType AddEntityType(
/// The name of the entity type to find.
/// The defining navigation of the entity type to find.
/// The defining entity type of the entity type to find.
- /// The entity type, or if none are found.
+ /// The entity type, or if none is found.
IMutableEntityType? FindEntityType(
[NotNull] string name,
[NotNull] string definingNavigationName,
diff --git a/src/EFCore/Metadata/IMutableNavigation.cs b/src/EFCore/Metadata/IMutableNavigation.cs
index b111c72a7e3..f6ff4c58354 100644
--- a/src/EFCore/Metadata/IMutableNavigation.cs
+++ b/src/EFCore/Metadata/IMutableNavigation.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableNavigation : INavigation, IMutableNavigationBase
+ public interface IMutableNavigation : IReadOnlyNavigation, IMutableNavigationBase
{
///
/// Gets the type that this navigation property belongs to.
@@ -26,7 +26,7 @@ public interface IMutableNavigation : INavigation, IMutableNavigationBase
new IMutableEntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => (IMutableEntityType)((INavigationBase)this).DeclaringEntityType;
+ get => (IMutableEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
}
///
@@ -35,7 +35,7 @@ public interface IMutableNavigation : INavigation, IMutableNavigationBase
new IMutableEntityType TargetEntityType
{
[DebuggerStepThrough]
- get => (IMutableEntityType)((INavigationBase)this).TargetEntityType;
+ get => (IMutableEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
@@ -44,7 +44,7 @@ public interface IMutableNavigation : INavigation, IMutableNavigationBase
new IMutableForeignKey ForeignKey
{
[DebuggerStepThrough]
- get => (IMutableForeignKey)((INavigation)this).ForeignKey;
+ get => (IMutableForeignKey)((IReadOnlyNavigation)this).ForeignKey;
}
///
@@ -53,7 +53,7 @@ public interface IMutableNavigation : INavigation, IMutableNavigationBase
new IMutableNavigation? Inverse
{
[DebuggerStepThrough]
- get => (IMutableNavigation?)((INavigation)this).Inverse;
+ get => (IMutableNavigation?)((IReadOnlyNavigation)this).Inverse;
}
///
diff --git a/src/EFCore/Metadata/IMutableNavigationBase.cs b/src/EFCore/Metadata/IMutableNavigationBase.cs
index 8f5d7a2d10a..43de45380a2 100644
--- a/src/EFCore/Metadata/IMutableNavigationBase.cs
+++ b/src/EFCore/Metadata/IMutableNavigationBase.cs
@@ -13,10 +13,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableNavigationBase : INavigationBase, IMutablePropertyBase
+ public interface IMutableNavigationBase : IReadOnlyNavigationBase, IMutablePropertyBase
{
///
/// Sets a value indicating whether this navigation should be eager loaded by default.
diff --git a/src/EFCore/Metadata/IMutableProperty.cs b/src/EFCore/Metadata/IMutableProperty.cs
index b92295b75dd..b77d81e3d12 100644
--- a/src/EFCore/Metadata/IMutableProperty.cs
+++ b/src/EFCore/Metadata/IMutableProperty.cs
@@ -7,14 +7,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// Represents a scalar property of an entity.
+ /// Represents a scalar property of an entity type.
///
///
/// 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 IMutableProperty : IProperty, IMutablePropertyBase
+ public interface IMutableProperty : IReadOnlyProperty, IMutablePropertyBase
{
///
/// Gets the type that this property belongs to.
diff --git a/src/EFCore/Metadata/IMutablePropertyBase.cs b/src/EFCore/Metadata/IMutablePropertyBase.cs
index f4c74e9c472..dd317804c9f 100644
--- a/src/EFCore/Metadata/IMutablePropertyBase.cs
+++ b/src/EFCore/Metadata/IMutablePropertyBase.cs
@@ -15,10 +15,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutablePropertyBase : IPropertyBase, IMutableAnnotatable
+ public interface IMutablePropertyBase : IReadOnlyPropertyBase, IMutableAnnotatable
{
///
/// Gets the type that this property belongs to.
diff --git a/src/EFCore/Metadata/IMutableServiceProperty.cs b/src/EFCore/Metadata/IMutableServiceProperty.cs
index 47d3bc55085..ecc98ba9619 100644
--- a/src/EFCore/Metadata/IMutableServiceProperty.cs
+++ b/src/EFCore/Metadata/IMutableServiceProperty.cs
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
{
///
///
- /// A in the Entity Framework model that represents an
+ /// A in the Entity Framework model that represents an
/// injected service from the .
///
///
@@ -17,7 +17,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableServiceProperty : IServiceProperty, IMutablePropertyBase
+ public interface IMutableServiceProperty : IReadOnlyServiceProperty, IMutablePropertyBase
{
///
/// Gets the type that this property belongs to.
diff --git a/src/EFCore/Metadata/IMutableSkipNavigation.cs b/src/EFCore/Metadata/IMutableSkipNavigation.cs
index 58468c9f1da..cce318ee7f7 100644
--- a/src/EFCore/Metadata/IMutableSkipNavigation.cs
+++ b/src/EFCore/Metadata/IMutableSkipNavigation.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
/// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBase
+ public interface IMutableSkipNavigation : IReadOnlySkipNavigation, IMutableNavigationBase
{
///
/// Gets the type that this navigation property belongs to.
@@ -26,7 +26,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBas
new IMutableEntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => (IMutableEntityType)((INavigationBase)this).DeclaringEntityType;
+ get => (IMutableEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
}
///
@@ -35,7 +35,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBas
new IMutableEntityType TargetEntityType
{
[DebuggerStepThrough]
- get => (IMutableEntityType)((INavigationBase)this).TargetEntityType;
+ get => (IMutableEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
@@ -44,7 +44,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBas
new IMutableEntityType? JoinEntityType
{
[DebuggerStepThrough]
- get => (IMutableEntityType?)((ISkipNavigation)this).JoinEntityType;
+ get => (IMutableEntityType?)((IReadOnlySkipNavigation)this).JoinEntityType;
}
///
@@ -53,7 +53,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBas
new IMutableForeignKey? ForeignKey
{
[DebuggerStepThrough]
- get => (IMutableForeignKey?)((ISkipNavigation)this).ForeignKey;
+ get => (IMutableForeignKey?)((IReadOnlySkipNavigation)this).ForeignKey;
}
///
@@ -70,7 +70,7 @@ public interface IMutableSkipNavigation : ISkipNavigation, IMutableNavigationBas
new IMutableSkipNavigation? Inverse
{
[DebuggerStepThrough]
- get => (IMutableSkipNavigation?)((ISkipNavigation)this).Inverse;
+ get => (IMutableSkipNavigation?)((IReadOnlySkipNavigation)this).Inverse;
}
///
diff --git a/src/EFCore/Metadata/IMutableTypeBase.cs b/src/EFCore/Metadata/IMutableTypeBase.cs
index e1a422d3bbe..c6c76212cca 100644
--- a/src/EFCore/Metadata/IMutableTypeBase.cs
+++ b/src/EFCore/Metadata/IMutableTypeBase.cs
@@ -14,10 +14,10 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// 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.
+ /// Once the model is built, represents a read-only view of the same metadata.
///
///
- public interface IMutableTypeBase : ITypeBase, IMutableAnnotatable
+ public interface IMutableTypeBase : IReadOnlyTypeBase, IMutableAnnotatable
{
///
/// Gets the model that this type belongs to.
diff --git a/src/EFCore/Metadata/INavigation.cs b/src/EFCore/Metadata/INavigation.cs
index 2f1d54d275d..5bd6f7373f8 100644
--- a/src/EFCore/Metadata/INavigation.cs
+++ b/src/EFCore/Metadata/INavigation.cs
@@ -2,7 +2,6 @@
// 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;
#nullable enable
@@ -11,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a navigation property which can be used to navigate a relationship.
///
- public interface INavigation : INavigationBase
+ public interface INavigation : IReadOnlyNavigation, INavigationBase
{
///
/// Gets the entity type that this navigation property belongs to.
@@ -19,7 +18,7 @@ public interface INavigation : INavigationBase
new IEntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => IsOnDependent ? ForeignKey.DeclaringEntityType : ForeignKey.PrincipalEntityType;
+ get => (IEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
}
///
@@ -28,93 +27,25 @@ public interface INavigation : INavigationBase
new IEntityType TargetEntityType
{
[DebuggerStepThrough]
- get => IsOnDependent ? ForeignKey.PrincipalEntityType : ForeignKey.DeclaringEntityType;
- }
-
- ///
- /// Gets the inverse navigation.
- ///
- new INavigation? Inverse
- {
- [DebuggerStepThrough]
- get => IsOnDependent ? ForeignKey.PrincipalToDependent : ForeignKey.DependentToPrincipal;
- }
-
- ///
- /// Gets a value indicating whether the navigation property is a collection property.
- ///
- new bool IsCollection
- {
- [DebuggerStepThrough]
- get => !IsOnDependent && !ForeignKey.IsUnique;
+ get => (IEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
/// 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 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.
- ///
- IEntityType INavigationBase.DeclaringEntityType
- {
- [DebuggerStepThrough]
- get => DeclaringEntityType;
- }
-
- ///
- /// Gets the entity type that this navigation property will hold an instance(s) of.
- ///
- IEntityType INavigationBase.TargetEntityType
+ new IForeignKey ForeignKey
{
[DebuggerStepThrough]
- get => TargetEntityType;
+ get => (IForeignKey)((IReadOnlyNavigation)this).ForeignKey;
}
///
/// Gets the inverse navigation.
///
- INavigationBase? INavigationBase.Inverse
- {
- [DebuggerStepThrough]
- get => Inverse;
- }
-
- ///
- /// Gets a value indicating whether the navigation property is a collection property.
- ///
- bool INavigationBase.IsCollection
+ new INavigation? Inverse
{
[DebuggerStepThrough]
- get => IsCollection;
+ get => (INavigation?)((IReadOnlyNavigation)this).Inverse;
}
-
- ///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
- ///
- /// The accessor.
- [DebuggerStepThrough]
- IClrCollectionAccessor? INavigationBase.GetCollectionAccessor()
- => GetCollectionAccessor();
}
}
diff --git a/src/EFCore/Metadata/INavigationBase.cs b/src/EFCore/Metadata/INavigationBase.cs
index c1dc068e03b..0c986dcb864 100644
--- a/src/EFCore/Metadata/INavigationBase.cs
+++ b/src/EFCore/Metadata/INavigationBase.cs
@@ -1,7 +1,11 @@
// 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;
+using System.Diagnostics;
+using System.Linq;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Utilities;
#nullable enable
@@ -10,50 +14,54 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// Represents a navigation property which can be used to navigate a relationship.
///
- public interface INavigationBase : IPropertyBase
+ public interface INavigationBase : IReadOnlyNavigationBase, IPropertyBase
{
///
/// Gets the entity type that this navigation property belongs to.
///
- IEntityType DeclaringEntityType { get; }
+ new IEntityType DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => (IEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
+ }
///
/// Gets the entity type that this navigation property will hold an instance(s) of.
///
- IEntityType TargetEntityType { get; }
+ new IEntityType TargetEntityType
+ {
+ [DebuggerStepThrough]
+ get => (IEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
+ }
///
/// Gets the inverse navigation.
///
- INavigationBase? Inverse { get; }
+ new INavigationBase? Inverse
+ {
+ [DebuggerStepThrough]
+ get => (INavigationBase?)((IReadOnlyNavigationBase)this).Inverse;
+ }
///
- /// Gets a value indicating whether the navigation property is a collection property.
+ /// Calls for a to mark it as loaded
+ /// when a no-tracking query has eagerly loaded this relationship.
///
- bool IsCollection { get; }
+ /// The entity for which the navigation has been loaded.
+ void SetIsLoadedWhenNoTracking([NotNull] object entity)
+ {
+ Check.NotNull(entity, nameof(entity));
- ///
- /// Gets a value indicating whether this navigation should be eager loaded by default.
- ///
- bool IsEagerLoaded
- => (bool?)this[CoreAnnotationNames.EagerLoaded] ?? false;
+ var serviceProperties = DeclaringEntityType
+ .GetDerivedTypesInclusive()
+ .Where(t => t.ClrType.IsInstanceOfType(entity))
+ .SelectMany(e => e.GetServiceProperties())
+ .Where(p => p.ClrType == typeof(ILazyLoader));
- ///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
- ///
- /// The accessor.
- IClrCollectionAccessor? GetCollectionAccessor();
-
- ///
- ///
- /// Gets the being used for this property.
- /// indicates that the default property access mode is being used.
- ///
- ///
- /// The access mode being used, or if the default access mode is being used.
- PropertyAccessMode IPropertyBase.GetPropertyAccessMode()
- => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
- ?? DeclaringType.GetNavigationAccessMode());
+ foreach (var serviceProperty in serviceProperties)
+ {
+ ((ILazyLoader?)serviceProperty.GetGetter().GetClrValue(entity))?.SetLoaded(entity, Name);
+ }
+ }
}
}
diff --git a/src/EFCore/Metadata/IProperty.cs b/src/EFCore/Metadata/IProperty.cs
index cdbff052e38..06b556806ab 100644
--- a/src/EFCore/Metadata/IProperty.cs
+++ b/src/EFCore/Metadata/IProperty.cs
@@ -1,54 +1,74 @@
// 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;
+using System.Collections.Generic;
+using System.Linq;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a scalar property of an entity.
+ /// Represents a scalar property of an entity type.
///
- public interface IProperty : IPropertyBase
+ public interface IProperty : IReadOnlyProperty, IPropertyBase
{
///
- /// Gets the entity type that this property belongs to.
+ /// Gets the type that this property belongs to.
///
- IEntityType DeclaringEntityType { get; }
+ new IEntityType DeclaringEntityType { get; }
///
- /// Gets a value indicating whether this property can contain .
+ /// Finds the first principal property that the given property is constrained by
+ /// if the given property is part of a foreign key.
///
- bool IsNullable { get; }
+ /// The first associated principal property, or if none exists.
+ IProperty? FindFirstPrincipal()
+ => (IProperty?)((IReadOnlyProperty)this).FindFirstPrincipal();
///
- /// Gets a value indicating when a value for this property will be generated by the database. Even when the
- /// property is set to be generated by the database, EF may still attempt to save a specific value (rather than
- /// having one generated by the database) when the entity is added and a value is assigned, or the property is
- /// marked as modified for an existing entity. See
- /// and for more information.
+ /// Finds the list of principal properties including the given property that the given property is constrained by
+ /// if the given property is part of a foreign key.
///
- ValueGenerated ValueGenerated { get; }
+ /// The list of all associated principal properties including the given property.
+ IReadOnlyList FindPrincipals()
+ => ((IReadOnlyProperty)this).FindPrincipals().Cast().ToList();
///
- /// Gets a value indicating whether this property is used as a concurrency token. When a property is configured
- /// as a concurrency token the value in the database will be checked when an instance of this entity type
- /// is updated or deleted during to ensure it has not changed since
- /// the instance was retrieved from the database. If it has changed, an exception will be thrown and the
- /// changes will not be applied to the database.
+ /// Gets all foreign keys that use this property (including composite foreign keys in which this property
+ /// is included).
///
- bool IsConcurrencyToken { get; }
+ ///
+ /// The foreign keys that use this property.
+ ///
+ IEnumerable GetContainingForeignKeys();
///
- ///
- /// Gets the being used for this property.
- /// indicates that the default property access mode is being used.
- ///
+ /// Gets all indexes that use this property (including composite indexes in which this property
+ /// is included).
///
- /// The access mode being used, or if the default access mode is being used.
- PropertyAccessMode IPropertyBase.GetPropertyAccessMode()
- => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
- ?? DeclaringType.GetPropertyAccessMode());
+ ///
+ /// The indexes that use this property.
+ ///
+ IEnumerable GetContainingIndexes();
+
+ ///
+ /// Gets the primary key that uses this property (including a composite primary key in which this property
+ /// is included).
+ ///
+ ///
+ /// The primary that use this property, or if it is not part of the primary key.
+ ///
+ IKey? FindContainingPrimaryKey()
+ => (IKey?)((IReadOnlyProperty)this).FindContainingPrimaryKey();
+
+ ///
+ /// Gets all primary or alternate keys that use this property (including composite keys in which this property
+ /// is included).
+ ///
+ ///
+ /// The primary and alternate keys that use this property.
+ ///
+ IEnumerable GetContainingKeys();
}
}
diff --git a/src/EFCore/Metadata/IPropertyBase.cs b/src/EFCore/Metadata/IPropertyBase.cs
index 97853ead3b4..9abe1a4f6a2 100644
--- a/src/EFCore/Metadata/IPropertyBase.cs
+++ b/src/EFCore/Metadata/IPropertyBase.cs
@@ -1,56 +1,38 @@
// 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.Reflection;
using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata.Internal;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Base type for navigation and scalar properties.
+ /// Base type for navigations and properties.
///
- public interface IPropertyBase : IAnnotatable
+ public interface IPropertyBase : IReadOnlyPropertyBase, IAnnotatable
{
- ///
- /// Gets the name of this property-like object.
- ///
- string Name { get; }
-
///
/// Gets the type that this property-like object belongs to.
///
- ITypeBase DeclaringType { get; }
-
- ///
- /// Gets the type of value that this property-like object holds.
- ///
- Type ClrType { get; }
-
- ///
- /// Gets the for the underlying CLR property for this property-like object.
- /// This may be for shadow properties or if mapped directly to a field.
- ///
- PropertyInfo? PropertyInfo { get; }
-
- ///
- /// Gets the for the underlying CLR field for this property-like object.
- /// This may be for shadow properties or if the backing field is not known.
- ///
- FieldInfo? FieldInfo { get; }
+ new ITypeBase DeclaringType
+ {
+ [DebuggerStepThrough]
+ get => (ITypeBase) ((IReadOnlyPropertyBase)this).DeclaringType;
+ }
///
///
- /// Gets the being used for this property.
- /// indicates that the default property access mode is being used.
+ /// Gets a for reading the value of this property.
+ ///
+ ///
+ /// Note that it is an error to call this method for a shadow property ()
+ /// since such a property has no associated .
///
///
- /// The access mode being used, or if the default access mode is being used.
- PropertyAccessMode GetPropertyAccessMode()
- => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
- ?? PropertyAccessMode.PreferField);
+ /// The accessor.
+ IClrPropertyGetter GetGetter();
}
}
diff --git a/src/EFCore/Metadata/IReadOnlyEntityType.cs b/src/EFCore/Metadata/IReadOnlyEntityType.cs
new file mode 100644
index 00000000000..7e30a84776d
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyEntityType.cs
@@ -0,0 +1,213 @@
+// 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.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Utilities;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents an entity type in a model.
+ ///
+ public interface IReadOnlyEntityType : IReadOnlyTypeBase
+ {
+ ///
+ /// Gets the base type of this entity type. Returns if this is not a derived type in an inheritance hierarchy.
+ ///
+ IReadOnlyEntityType? BaseType { get; }
+
+ ///
+ /// Gets the name of the defining navigation.
+ ///
+ [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
+ string? DefiningNavigationName => null;
+
+ ///
+ /// Gets the defining entity type.
+ ///
+ [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
+ IReadOnlyEntityType? DefiningEntityType => null;
+
+ ///
+ /// Gets a value indicating whether this entity type has a defining navigation.
+ ///
+ /// if this entity type has a defining navigation.
+ [Obsolete("Entity types with defining navigations have been replaced by shared-type entity types")]
+ public bool HasDefiningNavigation() => HasSharedClrType;
+
+ ///
+ /// Gets primary key for this entity type. Returns if no primary key is defined.
+ ///
+ /// The primary key, or if none is defined.
+ IReadOnlyKey? FindPrimaryKey();
+
+ ///
+ /// Gets the primary or alternate key that is defined on the given properties.
+ /// Returns if no key is defined for the given properties.
+ ///
+ /// The properties that make up the key.
+ /// The key, or if none is defined.
+ IReadOnlyKey? FindKey([NotNull] IReadOnlyList properties);
+
+ ///
+ /// Gets the primary and alternate keys for this entity type.
+ ///
+ /// The primary and alternate keys.
+ IEnumerable GetKeys();
+
+ ///
+ /// Gets the foreign key for the given properties that points to a given primary or alternate key.
+ /// Returns if no foreign key is found.
+ ///
+ /// The properties that the foreign key is defined on.
+ /// The primary or alternate key that is referenced.
+ ///
+ /// The entity type that the relationship targets. This may be different from the type that
+ /// is defined on when the relationship targets a derived type in an inheritance hierarchy (since the key is defined on the
+ /// base type of the hierarchy).
+ ///
+ /// The foreign key, or if none is defined.
+ IReadOnlyForeignKey? FindForeignKey(
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType);
+
+ ///
+ /// Gets the foreign keys defined on this entity type.
+ ///
+ /// The foreign keys defined on this entity type.
+ IEnumerable GetForeignKeys();
+
+ ///
+ /// Gets a skip navigation property on this entity type. Returns if no navigation property is found.
+ ///
+ /// The navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ IReadOnlySkipNavigation? FindSkipNavigation([NotNull] MemberInfo memberInfo)
+ => FindSkipNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
+
+ ///
+ /// Gets a skip navigation property on this entity type. Returns if no skip navigation property is found.
+ ///
+ /// The name of the navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ IReadOnlySkipNavigation? FindSkipNavigation([NotNull] string name);
+
+ ///
+ ///
+ /// Gets a skip navigation property on this entity type.
+ ///
+ ///
+ /// Does not return skip navigation properties defined on a base type.
+ /// Returns if no skip navigation property is found.
+ ///
+ ///
+ /// The name of the navigation property on the entity class.
+ /// The navigation property, or if none is found.
+ IReadOnlySkipNavigation? FindDeclaredSkipNavigation([NotNull] string name)
+ {
+ var navigation = FindSkipNavigation(name);
+ return navigation?.DeclaringEntityType == this ? navigation : null;
+ }
+
+ ///
+ ///
+ /// Gets all skip navigation properties declared on this entity type.
+ ///
+ ///
+ /// This method does not return skip navigation properties declared declared on base types.
+ /// It is useful when iterating over all entity types to avoid processing the same foreign key more than once.
+ /// Use to also return skip navigation properties declared on base types.
+ ///
+ ///
+ /// Declared skip navigations.
+ IEnumerable GetDeclaredSkipNavigations()
+ => GetSkipNavigations().Where(n => n.DeclaringEntityType == this);
+
+ ///
+ /// Gets the skip navigation properties on this entity type.
+ ///
+ /// All skip navigation properties on this entity type.
+ IEnumerable GetSkipNavigations();
+
+ ///
+ ///
+ /// Gets the unnamed index defined on the given properties. Returns if no such index is defined.
+ ///
+ ///
+ /// Named indexes will not be returned even if the list of properties matches.
+ ///
+ ///
+ /// The properties to find the index on.
+ /// The index, or if none is found.
+ IReadOnlyIndex? FindIndex([NotNull] IReadOnlyList properties);
+
+ ///
+ /// Gets the index with the given name. Returns if no such index exists.
+ ///
+ /// The name of the index to find.
+ /// The index, or if none is found.
+ IReadOnlyIndex? FindIndex([NotNull] string name);
+
+ ///
+ /// Gets the indexes defined on this entity type.
+ ///
+ /// The indexes defined on this entity type.
+ IEnumerable GetIndexes();
+
+ ///
+ ///
+ /// Gets the property with a given name. Returns if no property with the given name is defined.
+ ///
+ ///
+ /// This API only finds scalar properties and does not find navigation properties. Use
+ /// to find a navigation property.
+ ///
+ ///
+ /// The name of the property.
+ /// The property, or if none is found.
+ IReadOnlyProperty? FindProperty([NotNull] string name);
+
+ ///
+ ///
+ /// Gets the properties defined on this entity type.
+ ///
+ ///
+ /// This API only returns scalar properties and does not return navigation properties. Use
+ /// to get navigation properties.
+ ///
+ ///
+ /// The properties defined on this entity type.
+ IEnumerable GetProperties();
+
+ ///
+ ///
+ /// Gets the with a given name.
+ /// Returns if no property with the given name is defined.
+ ///
+ ///
+ /// This API only finds service properties and does not find scalar or navigation properties.
+ ///
+ ///
+ /// The name of the property.
+ /// The service property, or if none is found.
+ IReadOnlyServiceProperty? FindServiceProperty([NotNull] string name);
+
+ ///
+ ///
+ /// Gets all the defined on this entity type.
+ ///
+ ///
+ /// This API only returns service properties and does not return scalar or navigation properties.
+ ///
+ ///
+ /// The service properties defined on this entity type.
+ IEnumerable GetServiceProperties();
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyForeignKey.cs b/src/EFCore/Metadata/IReadOnlyForeignKey.cs
new file mode 100644
index 00000000000..d733f95e44a
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyForeignKey.cs
@@ -0,0 +1,89 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a relationship where a foreign key composed of properties on the dependent entity type
+ /// references a corresponding primary or alternate key on the principal entity type.
+ ///
+ public interface IReadOnlyForeignKey : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the dependent entity type. This may be different from the type that
+ /// are defined on when the relationship is defined a derived type in an inheritance hierarchy (since the properties
+ /// may be defined on a base type).
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+
+ ///
+ /// Gets the foreign key properties in the dependent entity.
+ ///
+ IReadOnlyList Properties { get; }
+
+ ///
+ /// Gets the principal entity type that this relationship targets. This may be different from the type that
+ /// is defined on when the relationship targets a derived type in an inheritance
+ /// hierarchy (since the key is defined on the base type of the hierarchy).
+ ///
+ IReadOnlyEntityType PrincipalEntityType { get; }
+
+ ///
+ /// Gets the primary or alternate key that the relationship targets.
+ ///
+ IReadOnlyKey PrincipalKey { get; }
+
+ ///
+ /// Gets the navigation property on the dependent entity type that points to the principal entity.
+ ///
+ IReadOnlyNavigation? DependentToPrincipal { get; }
+
+ ///
+ /// Gets the navigation property on the principal entity type that points to the dependent entity.
+ ///
+ IReadOnlyNavigation? PrincipalToDependent { get; }
+
+ ///
+ /// Gets a value indicating whether the values assigned to the foreign key properties are unique.
+ ///
+ bool IsUnique { get; }
+
+ ///
+ /// Gets a value indicating whether the principal entity is required.
+ /// If , the dependent entity must always be assigned to a valid principal entity.
+ ///
+ bool IsRequired { get; }
+
+ ///
+ /// Gets a value indicating whether the dependent entity is required.
+ /// If , the principal entity must always have a valid dependent entity assigned.
+ ///
+ bool IsRequiredDependent { get; }
+
+ ///
+ /// Gets or sets a value indicating whether this relationship defines an ownership.
+ /// If , the dependent entity must always be accessed via the navigation from the principal entity.
+ ///
+ bool IsOwnership { get; }
+
+ ///
+ /// Gets a value indicating how a delete operation is applied to dependent entities in the relationship when the
+ /// principal is deleted or the relationship is severed.
+ ///
+ DeleteBehavior DeleteBehavior { get; }
+
+ ///
+ /// Gets the skip navigations using this foreign key.
+ ///
+ /// The skip navigations using this foreign key.
+ IEnumerable GetReferencingSkipNavigations()
+ => 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/IReadOnlyIndex.cs b/src/EFCore/Metadata/IReadOnlyIndex.cs
new file mode 100644
index 00000000000..0c382a2811d
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyIndex.cs
@@ -0,0 +1,38 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents an index on a set of properties.
+ ///
+ public interface IReadOnlyIndex : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the properties that this index is defined on.
+ ///
+ IReadOnlyList Properties { get; }
+
+ ///
+ /// Gets the name of this index.
+ ///
+ string? Name { get; }
+
+ ///
+ /// Gets a value indicating whether the values assigned to the indexed properties are unique.
+ ///
+ bool IsUnique { get; }
+
+ ///
+ /// Gets the entity type the index is defined on. This may be different from the type that
+ /// are defined on when the index is defined a derived type in an inheritance hierarchy (since the properties
+ /// may be defined on a base type).
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyKey.cs b/src/EFCore/Metadata/IReadOnlyKey.cs
new file mode 100644
index 00000000000..b1892d3adc6
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyKey.cs
@@ -0,0 +1,28 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a primary or alternate key on an entity type.
+ ///
+ public interface IReadOnlyKey : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the properties that make up the key.
+ ///
+ IReadOnlyList Properties { get; }
+
+ ///
+ /// Gets the entity type the key is defined on. This may be different from the type that
+ /// are defined on when the key is defined a derived type in an inheritance hierarchy (since the properties
+ /// may be defined on a base type).
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyModel.cs b/src/EFCore/Metadata/IReadOnlyModel.cs
new file mode 100644
index 00000000000..09ba523a63b
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyModel.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Metadata about the shape of entities, the relationships between them, and how they map to
+ /// the database. A model is typically created by overriding the
+ /// method on a derived .
+ ///
+ public interface IReadOnlyModel : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets all entity types defined in the model.
+ ///
+ /// All entity types defined in the model.
+ IEnumerable GetEntityTypes();
+
+ ///
+ /// Gets the entity type with the given name. Returns if no entity type with the given name is found
+ /// or the given CLR type is being used by shared type entity type
+ /// or the entity type has a defining navigation.
+ ///
+ /// The name of the entity type to find.
+ /// The entity type, or if none is found.
+ IReadOnlyEntityType? FindEntityType([NotNull] string name);
+
+ ///
+ /// Gets the entity type for the given base name, defining navigation name
+ /// and the defining entity type. Returns if no matching entity type is found.
+ ///
+ /// The name of the entity type to find.
+ /// The defining navigation of the entity type to find.
+ /// The defining entity type of the entity type to find.
+ /// The entity type, or if none is found.
+ IReadOnlyEntityType? FindEntityType(
+ [NotNull] string name,
+ [NotNull] string definingNavigationName,
+ [NotNull] IReadOnlyEntityType definingEntityType);
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyNavigation.cs b/src/EFCore/Metadata/IReadOnlyNavigation.cs
new file mode 100644
index 00000000000..762bcce3525
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyNavigation.cs
@@ -0,0 +1,120 @@
+// 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;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a navigation property which can be used to navigate a relationship.
+ ///
+ public interface IReadOnlyNavigation : IReadOnlyNavigationBase
+ {
+ ///
+ /// Gets the entity type that this navigation property belongs to.
+ ///
+ new IReadOnlyEntityType DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => IsOnDependent ? ForeignKey.DeclaringEntityType : ForeignKey.PrincipalEntityType;
+ }
+
+ ///
+ /// Gets the entity type that this navigation property will hold an instance(s) of.
+ ///
+ new IReadOnlyEntityType TargetEntityType
+ {
+ [DebuggerStepThrough]
+ get => IsOnDependent ? ForeignKey.PrincipalEntityType : ForeignKey.DeclaringEntityType;
+ }
+
+ ///
+ /// Gets the inverse navigation.
+ ///
+ new IReadOnlyNavigation? Inverse
+ {
+ [DebuggerStepThrough]
+ get => IsOnDependent ? ForeignKey.PrincipalToDependent : ForeignKey.DependentToPrincipal;
+ }
+
+ ///
+ /// Gets a value indicating whether the navigation property is a collection property.
+ ///
+ new bool IsCollection
+ {
+ [DebuggerStepThrough]
+ get => !IsOnDependent && !ForeignKey.IsUnique;
+ }
+
+ ///
+ /// Gets the foreign key that defines the relationship this navigation property will navigate.
+ ///
+ IReadOnlyForeignKey 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 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.
+ ///
+ IReadOnlyEntityType IReadOnlyNavigationBase.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => DeclaringEntityType;
+ }
+
+ ///
+ /// Gets the entity type that this navigation property will hold an instance(s) of.
+ ///
+ IReadOnlyEntityType IReadOnlyNavigationBase.TargetEntityType
+ {
+ [DebuggerStepThrough]
+ get => TargetEntityType;
+ }
+
+ ///
+ /// Gets the inverse navigation.
+ ///
+ IReadOnlyNavigationBase? IReadOnlyNavigationBase.Inverse
+ {
+ [DebuggerStepThrough]
+ get => Inverse;
+ }
+
+ ///
+ /// Gets a value indicating whether the navigation property is a collection property.
+ ///
+ bool IReadOnlyNavigationBase.IsCollection
+ {
+ [DebuggerStepThrough]
+ get => IsCollection;
+ }
+
+ ///
+ /// Gets the for this navigation property, if it's a collection
+ /// navigation.
+ ///
+ /// The accessor.
+ [DebuggerStepThrough]
+ IClrCollectionAccessor? IReadOnlyNavigationBase.GetCollectionAccessor()
+ => GetCollectionAccessor();
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyNavigationBase.cs b/src/EFCore/Metadata/IReadOnlyNavigationBase.cs
new file mode 100644
index 00000000000..0925e495958
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyNavigationBase.cs
@@ -0,0 +1,59 @@
+// 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;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a navigation property which can be used to navigate a relationship.
+ ///
+ public interface IReadOnlyNavigationBase : IReadOnlyPropertyBase
+ {
+ ///
+ /// Gets the entity type that this navigation property belongs to.
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+
+ ///
+ /// Gets the entity type that this navigation property will hold an instance(s) of.
+ ///
+ IReadOnlyEntityType TargetEntityType { get; }
+
+ ///
+ /// Gets the inverse navigation.
+ ///
+ IReadOnlyNavigationBase? 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();
+
+ ///
+ ///
+ /// Gets the being used for this property.
+ /// indicates that the default property access mode is being used.
+ ///
+ ///
+ /// The access mode being used.
+ PropertyAccessMode IReadOnlyPropertyBase.GetPropertyAccessMode()
+ => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
+ ?? DeclaringType.GetNavigationAccessMode());
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyProperty.cs b/src/EFCore/Metadata/IReadOnlyProperty.cs
new file mode 100644
index 00000000000..8568e03caa6
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyProperty.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 Microsoft.EntityFrameworkCore.Metadata.Internal;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a scalar property of an entity type.
+ ///
+ public interface IReadOnlyProperty : IReadOnlyPropertyBase
+ {
+ ///
+ /// Gets the entity type that this property belongs to.
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+
+ ///
+ /// Gets a value indicating whether this property can contain .
+ ///
+ bool IsNullable { get; }
+
+ ///
+ /// Gets a value indicating when a value for this property will be generated by the database. Even when the
+ /// property is set to be generated by the database, EF may still attempt to save a specific value (rather than
+ /// having one generated by the database) when the entity is added and a value is assigned, or the property is
+ /// marked as modified for an existing entity. See
+ /// and for more information.
+ ///
+ ValueGenerated ValueGenerated { get; }
+
+ ///
+ /// Gets a value indicating whether this property is used as a concurrency token. When a property is configured
+ /// as a concurrency token the value in the database will be checked when an instance of this entity type
+ /// is updated or deleted during to ensure it has not changed since
+ /// the instance was retrieved from the database. If it has changed, an exception will be thrown and the
+ /// changes will not be applied to the database.
+ ///
+ bool IsConcurrencyToken { get; }
+
+ ///
+ ///
+ /// Gets the being used for this property.
+ /// indicates that the default property access mode is being used.
+ ///
+ ///
+ /// The access mode being used, or if the default access mode is being used.
+ PropertyAccessMode IReadOnlyPropertyBase.GetPropertyAccessMode()
+ => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
+ ?? DeclaringType.GetPropertyAccessMode());
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyPropertyBase.cs b/src/EFCore/Metadata/IReadOnlyPropertyBase.cs
new file mode 100644
index 00000000000..4f71f975375
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyPropertyBase.cs
@@ -0,0 +1,56 @@
+// 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.Reflection;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Base type for navigations and properties.
+ ///
+ public interface IReadOnlyPropertyBase : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the name of this property-like object.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the type that this property-like object belongs to.
+ ///
+ IReadOnlyTypeBase DeclaringType { get; }
+
+ ///
+ /// Gets the type of value that this property-like object holds.
+ ///
+ Type ClrType { get; }
+
+ ///
+ /// Gets the for the underlying CLR property for this property-like object.
+ /// This may be for shadow properties or if mapped directly to a field.
+ ///
+ PropertyInfo? PropertyInfo { get; }
+
+ ///
+ /// Gets the for the underlying CLR field for this property-like object.
+ /// This may be for shadow properties or if the backing field is not known.
+ ///
+ FieldInfo? FieldInfo { get; }
+
+ ///
+ ///
+ /// Gets the being used for this property.
+ /// indicates that the default property access mode is being used.
+ ///
+ ///
+ /// The access mode being used.
+ PropertyAccessMode GetPropertyAccessMode()
+ => (PropertyAccessMode)(this[CoreAnnotationNames.PropertyAccessMode]
+ ?? PropertyAccessMode.PreferField);
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyServiceProperty.cs b/src/EFCore/Metadata/IReadOnlyServiceProperty.cs
new file mode 100644
index 00000000000..2fb7e894d14
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyServiceProperty.cs
@@ -0,0 +1,24 @@
+// 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.
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a property on an entity type that represents an
+ /// injected service from the .
+ ///
+ public interface IReadOnlyServiceProperty : IReadOnlyPropertyBase
+ {
+ ///
+ /// Gets the entity type that this property belongs to.
+ ///
+ IReadOnlyEntityType DeclaringEntityType { get; }
+
+ ///
+ /// The for this property.
+ ///
+ ServiceParameterBinding? ParameterBinding { get; }
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlySkipNavigation.cs b/src/EFCore/Metadata/IReadOnlySkipNavigation.cs
new file mode 100644
index 00000000000..c1179d75311
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlySkipNavigation.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 System.Diagnostics;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a navigation property that is part of a relationship
+ /// that is forwarded through a third entity type.
+ ///
+ public interface IReadOnlySkipNavigation : IReadOnlyNavigationBase
+ {
+ ///
+ /// Gets the join type used by the foreign key.
+ ///
+ IReadOnlyEntityType? JoinEntityType
+ => IsOnDependent ? ForeignKey?.PrincipalEntityType : ForeignKey?.DeclaringEntityType;
+
+ ///
+ /// Gets the inverse skip navigation.
+ ///
+ new IReadOnlySkipNavigation Inverse { get; }
+
+ ///
+ /// Gets the inverse navigation.
+ ///
+ IReadOnlyNavigationBase IReadOnlyNavigationBase.Inverse
+ {
+ [DebuggerStepThrough]
+ get => Inverse;
+ }
+
+ ///
+ /// Gets the foreign key to the join type.
+ ///
+ IReadOnlyForeignKey? ForeignKey { get; }
+
+ ///
+ /// Gets a value indicating whether the navigation property is defined on the dependent side of the underlying foreign key.
+ ///
+ bool IsOnDependent { get; }
+
+ ///
+ /// Gets the for this navigation property, if it's a collection
+ /// navigation.
+ ///
+ /// The accessor.
+ IClrCollectionAccessor? IReadOnlyNavigationBase.GetCollectionAccessor()
+ => ((SkipNavigation)this).CollectionAccessor;
+ }
+}
diff --git a/src/EFCore/Metadata/IReadOnlyTypeBase.cs b/src/EFCore/Metadata/IReadOnlyTypeBase.cs
new file mode 100644
index 00000000000..936a968ebe3
--- /dev/null
+++ b/src/EFCore/Metadata/IReadOnlyTypeBase.cs
@@ -0,0 +1,48 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+
+#nullable enable
+
+namespace Microsoft.EntityFrameworkCore.Metadata
+{
+ ///
+ /// Represents a type in the model.
+ ///
+ public interface IReadOnlyTypeBase : IReadOnlyAnnotatable
+ {
+ ///
+ /// Gets the model that this type belongs to.
+ ///
+ IReadOnlyModel Model { get; }
+
+ ///
+ /// Gets the name of this type.
+ ///
+ string Name { get; }
+
+ ///
+ ///
+ /// Gets the CLR class that is used to represent instances of this type.
+ /// Returns if the type does not have a corresponding CLR class (known as a shadow type).
+ ///
+ ///
+ /// Shadow types are not currently supported in a model that is used at runtime with a .
+ /// Therefore, shadow types will only exist in migration model snapshots, etc.
+ ///
+ ///
+ Type ClrType { get; }
+
+ ///
+ /// Gets whether this entity type can share its ClrType with other entities.
+ ///
+ bool HasSharedClrType { get; }
+
+ ///
+ /// Gets whether this entity type has an indexer which is able to contain arbitrary properties.
+ ///
+ bool IsPropertyBag { get; }
+ }
+}
diff --git a/src/EFCore/Metadata/IServiceProperty.cs b/src/EFCore/Metadata/IServiceProperty.cs
index 0445539cebb..505b57abcd2 100644
--- a/src/EFCore/Metadata/IServiceProperty.cs
+++ b/src/EFCore/Metadata/IServiceProperty.cs
@@ -6,19 +6,14 @@
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// A in the Entity Framework model that represents an
+ /// Represents a property on an entity type that represents an
/// injected service from the .
///
- public interface IServiceProperty : IPropertyBase
+ public interface IServiceProperty : IReadOnlyServiceProperty, IPropertyBase
{
///
/// Gets the entity type that this property belongs to.
///
- IEntityType DeclaringEntityType { get; }
-
- ///
- /// The for this property.
- ///
- ServiceParameterBinding? ParameterBinding { get; }
+ new IEntityType DeclaringEntityType { get; }
}
}
diff --git a/src/EFCore/Metadata/ISkipNavigation.cs b/src/EFCore/Metadata/ISkipNavigation.cs
index 9d2287c0393..533a128244f 100644
--- a/src/EFCore/Metadata/ISkipNavigation.cs
+++ b/src/EFCore/Metadata/ISkipNavigation.cs
@@ -2,7 +2,6 @@
// 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;
#nullable enable
@@ -12,44 +11,51 @@ 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 : INavigationBase
+ public interface ISkipNavigation : IReadOnlySkipNavigation, INavigationBase
{
///
- /// Gets the join type used by the foreign key.
+ /// Gets the entity type that this navigation property belongs to.
///
- IEntityType? JoinEntityType
- => IsOnDependent ? ForeignKey?.PrincipalEntityType : ForeignKey?.DeclaringEntityType;
+ new IEntityType DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => (IEntityType)((IReadOnlyNavigationBase)this).DeclaringEntityType;
+ }
///
- /// Gets the inverse skip navigation.
+ /// Gets the entity type that this navigation property will hold an instance(s) of.
///
- new ISkipNavigation Inverse { get; }
+ new IEntityType TargetEntityType
+ {
+ [DebuggerStepThrough]
+ get => (IEntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
+ }
///
- /// Gets the inverse navigation.
+ /// Gets the join type used by the foreign key.
///
- INavigationBase INavigationBase.Inverse
+ new IEntityType JoinEntityType
{
[DebuggerStepThrough]
- get => Inverse;
+ get => (IEntityType)((IReadOnlySkipNavigation)this).JoinEntityType!;
}
///
/// Gets the foreign key to the join type.
///
- IForeignKey ForeignKey { get; }
-
- ///
- /// Gets a value indicating whether the navigation property is defined on the dependent side of the underlying foreign key.
- ///
- bool IsOnDependent { get; }
+ new IForeignKey ForeignKey
+ {
+ [DebuggerStepThrough]
+ get => (IForeignKey)((IReadOnlySkipNavigation)this).ForeignKey!;
+ }
///
- /// Gets the for this navigation property, if it's a collection
- /// navigation.
+ /// Gets the inverse skip navigation.
///
- /// The accessor.
- IClrCollectionAccessor? INavigationBase.GetCollectionAccessor()
- => ((SkipNavigation)this).CollectionAccessor;
+ new ISkipNavigation Inverse
+ {
+ [DebuggerStepThrough]
+ get => (ISkipNavigation)((IReadOnlySkipNavigation)this).Inverse!;
+ }
}
}
diff --git a/src/EFCore/Metadata/ITypeBase.cs b/src/EFCore/Metadata/ITypeBase.cs
index afb6f56e4b5..1be61b3e757 100644
--- a/src/EFCore/Metadata/ITypeBase.cs
+++ b/src/EFCore/Metadata/ITypeBase.cs
@@ -1,50 +1,20 @@
// 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 Microsoft.EntityFrameworkCore.Infrastructure;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
namespace Microsoft.EntityFrameworkCore.Metadata
{
///
- /// Represents a type in an .
+ /// Represents a type in the model.
///
- public interface ITypeBase : IAnnotatable
+ public interface ITypeBase : IReadOnlyTypeBase, IAnnotatable
{
///
/// Gets the model that this type belongs to.
///
- IModel Model { get; }
-
- ///
- /// Gets the name of this type.
- ///
- string Name { get; }
-
- ///
- ///
- /// Gets the CLR class that is used to represent instances of this type.
- /// Returns if the type does not have a corresponding CLR class (known as a shadow type).
- ///
- ///
- /// Shadow types are not currently supported in a model that is used at runtime with a .
- /// Therefore, shadow types will only exist in migration model snapshots, etc.
- ///
- ///
- Type ClrType { get; }
-
- ///
- /// Gets whether this entity type can share its ClrType with other entities.
- ///
- [CA.MemberNotNullWhen(true, nameof(ClrType))]
- bool HasSharedClrType { get; }
-
- ///
- /// Gets whether this entity type has an indexer which is able to contain arbitrary properties.
- ///
- bool IsPropertyBag { get; }
+ new IModel Model { get; }
}
}
diff --git a/src/EFCore/Metadata/IndexComparer.cs b/src/EFCore/Metadata/IndexComparer.cs
index fadad5c1963..1153b85fac1 100644
--- a/src/EFCore/Metadata/IndexComparer.cs
+++ b/src/EFCore/Metadata/IndexComparer.cs
@@ -12,14 +12,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// An implementation of and to compare
- /// instances.
+ /// instances.
///
///
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
///
///
- public sealed class IndexComparer : IEqualityComparer, IComparer
+ public sealed class IndexComparer : IEqualityComparer, IComparer
{
private IndexComparer()
{
@@ -36,7 +36,7 @@ private IndexComparer()
/// The first object to compare.
/// The second object to compare.
/// A negative number if 'x' is less than 'y'; a positive number if 'x' is greater than 'y'; zero otherwise.
- public int Compare(IIndex? x, IIndex? y)
+ public int Compare(IReadOnlyIndex? x, IReadOnlyIndex? y)
{
var result = PropertyListComparer.Instance.Compare(x?.Properties, y?.Properties);
return result != 0 ? result : EntityTypeFullNameComparer.Instance.Compare(x?.DeclaringEntityType, y?.DeclaringEntityType);
@@ -48,7 +48,7 @@ public int Compare(IIndex? x, IIndex? y)
/// The first object to compare.
/// The second object to compare.
/// if the specified objects are equal; otherwise, .
- public bool Equals(IIndex? x, IIndex? y)
+ public bool Equals(IReadOnlyIndex? x, IReadOnlyIndex? y)
=> Compare(x, y) == 0;
///
@@ -56,7 +56,7 @@ public bool Equals(IIndex? x, IIndex? y)
///
/// The for which a hash code is to be returned.
/// A hash code for the specified object.
- public int GetHashCode(IIndex obj)
+ public int GetHashCode(IReadOnlyIndex obj)
{
var hashCode = new HashCode();
hashCode.Add(obj.Properties, PropertyListComparer.Instance);
diff --git a/src/EFCore/Metadata/Internal/ConstructorBindingFactory.cs b/src/EFCore/Metadata/Internal/ConstructorBindingFactory.cs
index a9b89856260..427a225d98c 100644
--- a/src/EFCore/Metadata/Internal/ConstructorBindingFactory.cs
+++ b/src/EFCore/Metadata/Internal/ConstructorBindingFactory.cs
@@ -82,9 +82,9 @@ public virtual bool TryBindConstructor(
out unboundParameters);
private bool TryBindConstructor(
- IEntityType entityType,
+ IReadOnlyEntityType entityType,
ConstructorInfo constructor,
- Func bind,
+ Func bind,
[CA.NotNullWhen(true)] out InstantiationBinding? binding,
[CA.NotNullWhen(false)] out IEnumerable? unboundParameters)
{
@@ -92,7 +92,7 @@ private bool TryBindConstructor(
= constructor.GetParameters().Select(
p => (p, string.IsNullOrEmpty(p.Name)
? null
- : _propertyFactory.FindParameter(entityType, p.ParameterType, p.Name)
+ : _propertyFactory.FindParameter((IEntityType)entityType, p.ParameterType, p.Name)
?? bind(_factories.FindFactory(p.ParameterType, p.Name), entityType, p.ParameterType, p.Name)))
.ToList();
diff --git a/src/EFCore/Metadata/Internal/ContextParameterBindingFactory.cs b/src/EFCore/Metadata/Internal/ContextParameterBindingFactory.cs
index 1878edc1ffe..9c87cbb2509 100644
--- a/src/EFCore/Metadata/Internal/ContextParameterBindingFactory.cs
+++ b/src/EFCore/Metadata/Internal/ContextParameterBindingFactory.cs
@@ -36,7 +36,7 @@ public virtual bool CanBind(
public virtual ParameterBinding Bind(IMutableEntityType entityType, Type parameterType, string parameterName)
=> new ContextParameterBinding(
parameterType,
- entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -50,6 +50,6 @@ public virtual ParameterBinding Bind(
string parameterName)
=> new ContextParameterBinding(
parameterType,
- entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
}
}
diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs
index bce31c04e93..474d697f744 100644
--- a/src/EFCore/Metadata/Internal/EntityType.cs
+++ b/src/EFCore/Metadata/Internal/EntityType.cs
@@ -28,7 +28,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 EntityType : TypeBase, IMutableEntityType, IConventionEntityType
+ public class EntityType : TypeBase, IMutableEntityType, IConventionEntityType, IEntityType
{
private const string DynamicProxyGenAssemblyName = "DynamicProxyGenAssembly2";
@@ -41,7 +41,7 @@ private readonly SortedDictionary _navigations
private readonly SortedDictionary _skipNavigations
= new(StringComparer.Ordinal);
- private readonly SortedDictionary, Index> _unnamedIndexes
+ private readonly SortedDictionary, Index> _unnamedIndexes
= new(PropertyListComparer.Instance);
private readonly SortedDictionary _namedIndexes
@@ -49,7 +49,7 @@ private readonly SortedDictionary _namedIndexes
private readonly SortedDictionary _properties;
- private readonly SortedDictionary, Key> _keys
+ private readonly SortedDictionary, Key> _keys
= new(PropertyListComparer.Instance);
private readonly SortedDictionary _serviceProperties
@@ -77,8 +77,8 @@ private readonly SortedDictionary _serviceProperties
private Func? _shadowValuesFactory;
private Func? _emptyShadowValuesFactory;
private Func? _instanceFactory;
- private IProperty[]? _propagatingProperties;
- private IProperty[]? _generatingProperties;
+ private IProperty[]? _foreignKeyProperties;
+ private IProperty[]? _valueGeneratingProperties;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -403,6 +403,11 @@ public virtual ISet GetDirectlyDerivedTypes()
///
public virtual IEnumerable GetDerivedTypes()
{
+ if (_directlyDerivedTypes.Count == 0)
+ {
+ return Enumerable.Empty();
+ }
+
var derivedTypes = new List();
var type = this;
var currentTypeIndex = 0;
@@ -466,7 +471,7 @@ private bool InheritsFrom(EntityType entityType)
///
[DebuggerStepThrough]
public virtual EntityType RootType()
- => (EntityType)((IEntityType)this).GetRootType();
+ => (EntityType)((IReadOnlyEntityType)this).GetRootType();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -779,7 +784,7 @@ private void UpdatePrimaryKeyConfigurationSource(ConfigurationSource configurati
/// 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 Key? FindKey([NotNull] IProperty property)
+ public virtual Key? FindKey([NotNull] IReadOnlyProperty property)
=> FindKey(new[] { property });
///
@@ -788,7 +793,7 @@ private void UpdatePrimaryKeyConfigurationSource(ConfigurationSource configurati
/// 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 Key? FindKey([NotNull] IReadOnlyList properties)
+ public virtual Key? FindKey([NotNull] IReadOnlyList properties)
{
Check.HasNoNulls(properties, nameof(properties));
Check.NotEmpty(properties, nameof(properties));
@@ -811,7 +816,7 @@ public virtual IEnumerable GetDeclaredKeys()
/// 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 Key? FindDeclaredKey([NotNull] IReadOnlyList properties)
+ public virtual Key? FindDeclaredKey([NotNull] IReadOnlyList properties)
=> _keys.TryGetValue(Check.NotEmpty(properties, nameof(properties)), out var key)
? key
: null;
@@ -822,7 +827,7 @@ public virtual IEnumerable GetDeclaredKeys()
/// 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 Key? RemoveKey([NotNull] IReadOnlyList properties)
+ public virtual Key? RemoveKey([NotNull] IReadOnlyList properties)
{
Check.NotEmpty(properties, nameof(properties));
@@ -1043,7 +1048,7 @@ public virtual void OnForeignKeyUpdated([NotNull] 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 IEnumerable FindForeignKeys([NotNull] IProperty property)
+ public virtual IEnumerable FindForeignKeys([NotNull] IReadOnlyProperty property)
=> FindForeignKeys(new[] { property });
///
@@ -1052,7 +1057,7 @@ public virtual IEnumerable FindForeignKeys([NotNull] IProperty prope
/// 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 IEnumerable FindForeignKeys([NotNull] IReadOnlyList properties)
+ public virtual IEnumerable FindForeignKeys([NotNull] IReadOnlyList properties)
{
Check.HasNoNulls(properties, nameof(properties));
Check.NotEmpty(properties, nameof(properties));
@@ -1071,9 +1076,9 @@ public virtual IEnumerable FindForeignKeys([NotNull] IReadOnlyList
public virtual ForeignKey? FindForeignKey(
- [NotNull] IProperty property,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyProperty property,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
=> FindForeignKey(
new[] { property }, principalKey, principalEntityType);
@@ -1084,9 +1089,9 @@ public virtual IEnumerable FindForeignKeys([NotNull] IReadOnlyList
public virtual ForeignKey? FindForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
{
Check.HasNoNulls(properties, nameof(properties));
Check.NotEmpty(properties, nameof(properties));
@@ -1174,7 +1179,7 @@ public virtual IEnumerable GetForeignKeys()
/// 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 IEnumerable FindDeclaredForeignKeys([NotNull] IReadOnlyList properties)
+ public virtual IEnumerable FindDeclaredForeignKeys([NotNull] IReadOnlyList properties)
{
Check.NotEmpty(properties, nameof(properties));
@@ -1190,9 +1195,9 @@ public virtual IEnumerable FindDeclaredForeignKeys([NotNull] IReadOn
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual ForeignKey? FindDeclaredForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
{
Check.NotEmpty(properties, nameof(properties));
Check.NotNull(principalKey, nameof(principalKey));
@@ -1222,7 +1227,7 @@ public virtual IEnumerable FindDeclaredForeignKeys([NotNull] IReadOn
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindDerivedForeignKeys(
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> _directlyDerivedTypes.Count == 0
? Enumerable.Empty()
: GetDerivedTypes().SelectMany(et => et.FindDeclaredForeignKeys(properties));
@@ -1234,9 +1239,9 @@ public virtual IEnumerable FindDerivedForeignKeys(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindDerivedForeignKeys(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
=> _directlyDerivedTypes.Count == 0
? Enumerable.Empty()
: (IEnumerable)GetDerivedTypes().Select(et => et.FindDeclaredForeignKey(properties, principalKey, principalEntityType))
@@ -1249,7 +1254,7 @@ public virtual IEnumerable FindDerivedForeignKeys(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindForeignKeysInHierarchy(
- [NotNull] IReadOnlyList properties)
+ [NotNull] IReadOnlyList properties)
=> _directlyDerivedTypes.Count == 0
? FindForeignKeys(properties)
: FindForeignKeys(properties).Concat(FindDerivedForeignKeys(properties));
@@ -1261,9 +1266,9 @@ public virtual IEnumerable FindForeignKeysInHierarchy(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindForeignKeysInHierarchy(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
=> _directlyDerivedTypes.Count == 0
? ToEnumerable(FindForeignKey(properties, principalKey, principalEntityType))
: ToEnumerable(FindForeignKey(properties, principalKey, principalEntityType))
@@ -1276,9 +1281,9 @@ public virtual IEnumerable FindForeignKeysInHierarchy(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual ForeignKey? RemoveForeignKey(
- [NotNull] IReadOnlyList properties,
- [NotNull] IKey principalKey,
- [NotNull] IEntityType principalEntityType)
+ [NotNull] IReadOnlyList properties,
+ [NotNull] IReadOnlyKey principalKey,
+ [NotNull] IReadOnlyEntityType principalEntityType)
{
Check.NotEmpty(properties, nameof(properties));
@@ -1506,11 +1511,7 @@ private Navigation AddNavigation(MemberIdentity navigationMember, ForeignKey for
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual Navigation? FindNavigation([NotNull] string name)
- {
- Check.NotEmpty(name, nameof(name));
-
- return FindDeclaredNavigation(name) ?? _baseType?.FindNavigation(name);
- }
+ => (Navigation?)((IReadOnlyEntityType)this).FindNavigation(name);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1519,7 +1520,7 @@ private Navigation AddNavigation(MemberIdentity navigationMember, ForeignKey for
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual Navigation? FindNavigation([NotNull] MemberInfo memberInfo)
- => FindNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
+ => (Navigation?)((IReadOnlyEntityType)this).FindNavigation(Check.NotNull(memberInfo, nameof(memberInfo)).GetSimpleMemberName());
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -2048,7 +2049,7 @@ private void UpdatePropertyIndexes(IReadOnlyList properties, Index ind
/// 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 Index? FindIndex([NotNull] IProperty property)
+ public virtual Index? FindIndex([NotNull] IReadOnlyProperty property)
=> FindIndex(new[] { property });
///
@@ -2057,7 +2058,7 @@ private void UpdatePropertyIndexes(IReadOnlyList properties, Index ind
/// 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 Index? FindIndex([NotNull] IReadOnlyList properties)
+ public virtual Index? FindIndex([NotNull] IReadOnlyList properties)
{
Check.HasNoNulls(properties, nameof(properties));
Check.NotEmpty(properties, nameof(properties));
@@ -2106,7 +2107,7 @@ public virtual IEnumerable GetDerivedIndexes()
/// 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 Index? FindDeclaredIndex([NotNull] IReadOnlyList properties)
+ public virtual Index? FindDeclaredIndex([NotNull] IReadOnlyList properties)
=> _unnamedIndexes.TryGetValue(Check.NotEmpty(properties, nameof(properties)), out var index)
? index
: null;
@@ -2128,7 +2129,7 @@ public virtual IEnumerable GetDerivedIndexes()
/// 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 IEnumerable FindDerivedIndexes([NotNull] IReadOnlyList properties)
+ public virtual IEnumerable FindDerivedIndexes([NotNull] IReadOnlyList properties)
=> _directlyDerivedTypes.Count == 0
? Enumerable.Empty()
: (IEnumerable)GetDerivedTypes().Select(et => et.FindDeclaredIndex(properties)).Where(i => i != null);
@@ -2152,7 +2153,7 @@ public virtual IEnumerable FindDerivedIndexes([NotNull] string name)
/// 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 IEnumerable FindIndexesInHierarchy([NotNull] IReadOnlyList properties)
+ public virtual IEnumerable FindIndexesInHierarchy([NotNull] IReadOnlyList properties)
=> _directlyDerivedTypes.Count == 0
? ToEnumerable(FindIndex(properties))
: ToEnumerable(FindIndex(properties)).Concat(FindDerivedIndexes(properties));
@@ -2174,7 +2175,7 @@ public virtual IEnumerable FindIndexesInHierarchy([NotNull] string name)
/// 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 Index? RemoveIndex([NotNull] IReadOnlyList properties)
+ public virtual Index? RemoveIndex([NotNull] IReadOnlyList properties)
{
Check.NotEmpty(properties, nameof(properties));
@@ -2470,6 +2471,8 @@ public virtual IEnumerable FindPropertiesInHierarchy([NotNull] string
///
public virtual IReadOnlyList? FindProperties([NotNull] IReadOnlyList propertyNames)
{
+ Check.NotNull(propertyNames, nameof(propertyNames));
+
var properties = new List(propertyNames.Count);
foreach (var propertyName in propertyNames)
{
@@ -2708,9 +2711,9 @@ public virtual Func InstanceFactory
/// 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 IReadOnlyList PropagatingProperties
+ public virtual IReadOnlyList ForeignKeyProperties
=> NonCapturingLazyInitializer.EnsureInitialized(
- ref _propagatingProperties, this,
+ ref _foreignKeyProperties, this,
static entityType =>
{
entityType.EnsureReadOnly();
@@ -2724,9 +2727,9 @@ public virtual IReadOnlyList PropagatingProperties
/// 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 IReadOnlyList GeneratingProperties
+ public virtual IReadOnlyList ValueGeneratingProperties
=> NonCapturingLazyInitializer.EnsureInitialized(
- ref _generatingProperties, this,
+ ref _valueGeneratingProperties, this,
static entityType =>
{
entityType.EnsureReadOnly();
@@ -2970,7 +2973,7 @@ public virtual IEnumerable GetDeclaredServiceProperties()
var data = new List>();
var valueConverters = new Dictionary(StringComparer.Ordinal);
var properties = GetProperties()
- .Concat(GetNavigations())
+ .Concat(GetNavigations())
.Concat(GetSkipNavigations())
.ToDictionary(p => p.Name);
foreach (var rawSeed in _data)
@@ -2986,7 +2989,7 @@ public virtual IEnumerable GetDeclaredServiceProperties()
{
ValueConverter? valueConverter = null;
if (providerValues
- && propertyBase is IProperty property
+ && propertyBase is IReadOnlyProperty property
&& !valueConverters.TryGetValue(propertyBase.Name, out valueConverter))
{
valueConverter = property.GetTypeMapping().Converter;
@@ -3040,7 +3043,7 @@ public virtual IEnumerable GetDeclaredServiceProperties()
if (providerValues
&& !valueConverters.TryGetValue(propertyBase.Name, out valueConverter))
{
- if (propertyBase is IProperty property)
+ if (propertyBase is IReadOnlyProperty property)
{
valueConverter = property.GetTypeMapping().Converter;
}
@@ -3280,7 +3283,7 @@ private void CheckDiscriminatorProperty(Property? property)
/// 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 void CheckDiscriminatorValue([NotNull] IEntityType entityType, [CanBeNull] object? value)
+ public virtual void CheckDiscriminatorValue([NotNull] IReadOnlyEntityType entityType, [CanBeNull] object? value)
{
if (value is null)
{
@@ -3345,7 +3348,7 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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.
///
- IModel ITypeBase.Model
+ IReadOnlyModel IReadOnlyTypeBase.Model
{
[DebuggerStepThrough]
get => Model;
@@ -3393,7 +3396,19 @@ IConventionModel IConventionEntityType.Model
/// 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? IEntityType.BaseType
+ IModel ITypeBase.Model
+ {
+ [DebuggerStepThrough]
+ get => Model;
+ }
+
+ ///
+ /// 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.
+ ///
+ IReadOnlyEntityType? IReadOnlyEntityType.BaseType
{
[DebuggerStepThrough]
get => _baseType;
@@ -3423,6 +3438,28 @@ IConventionModel IConventionEntityType.Model
get => BaseType;
}
+ ///
+ /// 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? IEntityType.BaseType
+ {
+ [DebuggerStepThrough]
+ get => BaseType;
+ }
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDirectlyDerivedTypes()
+ => GetDirectlyDerivedTypes();
+
///
/// 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
@@ -3472,7 +3509,7 @@ IConventionModel IConventionEntityType.Model
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IKey? IEntityType.FindPrimaryKey()
+ IReadOnlyKey? IReadOnlyEntityType.FindPrimaryKey()
=> FindPrimaryKey();
///
@@ -3495,6 +3532,16 @@ IConventionModel IConventionEntityType.Model
IConventionKey? IConventionEntityType.FindPrimaryKey()
=> FindPrimaryKey();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IKey? IEntityType.FindPrimaryKey()
+ => FindPrimaryKey();
+
///
/// 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
@@ -3524,7 +3571,7 @@ IMutableKey IMutableEntityType.AddKey(IReadOnlyList properties
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IKey? IEntityType.FindKey(IReadOnlyList properties)
+ IReadOnlyKey? IReadOnlyEntityType.FindKey(IReadOnlyList properties)
=> FindKey(properties);
///
@@ -3534,7 +3581,7 @@ IMutableKey IMutableEntityType.AddKey(IReadOnlyList properties
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IMutableKey? IMutableEntityType.FindKey(IReadOnlyList properties)
+ IMutableKey? IMutableEntityType.FindKey(IReadOnlyList properties)
=> FindKey(properties);
///
@@ -3544,7 +3591,7 @@ IMutableKey IMutableEntityType.AddKey(IReadOnlyList properties
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IConventionKey? IConventionEntityType.FindKey(IReadOnlyList properties)
+ IConventionKey? IConventionEntityType.FindKey(IReadOnlyList properties)
=> FindKey(properties);
///
@@ -3554,7 +3601,27 @@ IMutableKey IMutableEntityType.AddKey(IReadOnlyList properties
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetKeys()
+ IKey? IEntityType.FindKey(IReadOnlyList properties)
+ => FindKey(properties);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredKeys()
+ => GetDeclaredKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyEntityType.GetKeys()
=> GetKeys();
///
@@ -3577,6 +3644,16 @@ IEnumerable IMutableEntityType.GetKeys()
IEnumerable IConventionEntityType.GetKeys()
=> GetKeys();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetKeys()
+ => GetKeys();
+
///
/// 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
@@ -3644,10 +3721,10 @@ IMutableForeignKey IMutableEntityType.AddForeignKey(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IForeignKey? IEntityType.FindForeignKey(
- IReadOnlyList properties,
- IKey principalKey,
- IEntityType principalEntityType)
+ IReadOnlyForeignKey? IReadOnlyEntityType.FindForeignKey(
+ IReadOnlyList properties,
+ IReadOnlyKey principalKey,
+ IReadOnlyEntityType principalEntityType)
=> FindForeignKey(properties, principalKey, principalEntityType);
///
@@ -3658,9 +3735,9 @@ IMutableForeignKey IMutableEntityType.AddForeignKey(
///
[DebuggerStepThrough]
IMutableForeignKey? IMutableEntityType.FindForeignKey(
- IReadOnlyList properties,
- IKey principalKey,
- IEntityType principalEntityType)
+ IReadOnlyList properties,
+ IReadOnlyKey principalKey,
+ IReadOnlyEntityType principalEntityType)
=> FindForeignKey(properties, principalKey, principalEntityType);
///
@@ -3671,9 +3748,9 @@ IMutableForeignKey IMutableEntityType.AddForeignKey(
///
[DebuggerStepThrough]
IConventionForeignKey? IConventionEntityType.FindForeignKey(
- IReadOnlyList properties,
- IKey principalKey,
- IEntityType principalEntityType)
+ IReadOnlyList properties,
+ IReadOnlyKey principalKey,
+ IReadOnlyEntityType principalEntityType)
=> FindForeignKey(properties, principalKey, principalEntityType);
///
@@ -3683,7 +3760,40 @@ IMutableForeignKey IMutableEntityType.AddForeignKey(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetForeignKeys()
+ IForeignKey? IEntityType.FindForeignKey(
+ IReadOnlyList properties,
+ IReadOnlyKey principalKey,
+ IReadOnlyEntityType principalEntityType)
+ => FindForeignKey(properties, principalKey, principalEntityType);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.FindForeignKeys(IReadOnlyList properties)
+ => FindForeignKeys(properties);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.FindDeclaredForeignKeys(IReadOnlyList properties)
+ => FindDeclaredForeignKeys(properties);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyEntityType.GetForeignKeys()
=> GetForeignKeys();
///
@@ -3706,6 +3816,56 @@ IEnumerable IMutableEntityType.GetForeignKeys()
IEnumerable IConventionEntityType.GetForeignKeys()
=> GetForeignKeys();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetForeignKeys()
+ => GetForeignKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredForeignKeys()
+ => GetDeclaredForeignKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDerivedForeignKeys()
+ => GetDerivedForeignKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredReferencingForeignKeys()
+ => GetDeclaredReferencingForeignKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetReferencingForeignKeys()
+ => GetReferencingForeignKeys();
+
///
/// 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
@@ -3726,6 +3886,26 @@ IEnumerable IConventionEntityType.GetForeignKeys()
IConventionForeignKey? IConventionEntityType.RemoveForeignKey(IConventionForeignKey foreignKey)
=> RemoveForeignKey((ForeignKey)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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredNavigations()
+ => GetDeclaredNavigations();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ INavigation? IEntityType.FindDeclaredNavigation(string name)
+ => FindDeclaredNavigation(name);
+
///
/// 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
@@ -3768,7 +3948,7 @@ IMutableSkipNavigation IMutableEntityType.AddSkipNavigation(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- ISkipNavigation? IEntityType.FindSkipNavigation(MemberInfo memberInfo)
+ IReadOnlySkipNavigation? IReadOnlyEntityType.FindSkipNavigation(MemberInfo memberInfo)
=> FindSkipNavigation(memberInfo);
///
@@ -3778,7 +3958,7 @@ IMutableSkipNavigation IMutableEntityType.AddSkipNavigation(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- ISkipNavigation? IEntityType.FindSkipNavigation(string name)
+ IReadOnlySkipNavigation? IReadOnlyEntityType.FindSkipNavigation(string name)
=> FindSkipNavigation(name);
///
@@ -3808,7 +3988,17 @@ IMutableSkipNavigation IMutableEntityType.AddSkipNavigation(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- ISkipNavigation? IEntityType.FindDeclaredSkipNavigation(string name)
+ ISkipNavigation? IEntityType.FindSkipNavigation(string name)
+ => FindSkipNavigation(name);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IReadOnlySkipNavigation? IReadOnlyEntityType.FindDeclaredSkipNavigation(string name)
=> FindDeclaredSkipNavigation(name);
///
@@ -3818,7 +4008,7 @@ IMutableSkipNavigation IMutableEntityType.AddSkipNavigation(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetDeclaredSkipNavigations()
+ IEnumerable IReadOnlyEntityType.GetDeclaredSkipNavigations()
=> GetDeclaredSkipNavigations();
///
@@ -3828,7 +4018,7 @@ IEnumerable IEntityType.GetDeclaredSkipNavigations()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetSkipNavigations()
+ IEnumerable IReadOnlyEntityType.GetSkipNavigations()
=> GetSkipNavigations();
///
@@ -3851,6 +4041,16 @@ IEnumerable IMutableEntityType.GetSkipNavigations()
IEnumerable IConventionEntityType.GetSkipNavigations()
=> GetSkipNavigations();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetSkipNavigations()
+ => GetSkipNavigations();
+
///
/// 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
@@ -3926,7 +4126,7 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IIndex? IEntityType.FindIndex(IReadOnlyList properties)
+ IReadOnlyIndex? IReadOnlyEntityType.FindIndex(IReadOnlyList properties)
=> FindIndex(properties);
///
@@ -3936,8 +4136,8 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IIndex? IEntityType.FindIndex(string name)
- => FindIndex(name);
+ IMutableIndex? IMutableEntityType.FindIndex(IReadOnlyList properties)
+ => FindIndex(properties);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -3946,7 +4146,7 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IMutableIndex? IMutableEntityType.FindIndex(IReadOnlyList properties)
+ IConventionIndex? IConventionEntityType.FindIndex(IReadOnlyList properties)
=> FindIndex(properties);
///
@@ -3956,7 +4156,17 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IMutableIndex? IMutableEntityType.FindIndex(string name)
+ IIndex? IEntityType.FindIndex(IReadOnlyList properties)
+ => FindIndex(properties);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IReadOnlyIndex? IReadOnlyEntityType.FindIndex(string name)
=> FindIndex(name);
///
@@ -3966,8 +4176,8 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IConventionIndex? IConventionEntityType.FindIndex(IReadOnlyList properties)
- => FindIndex(properties);
+ IMutableIndex? IMutableEntityType.FindIndex(string name)
+ => FindIndex(name);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -3986,7 +4196,37 @@ IMutableIndex IMutableEntityType.AddIndex(IReadOnlyList proper
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetIndexes()
+ IIndex? IEntityType.FindIndex(string name)
+ => FindIndex(name);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredIndexes()
+ => GetDeclaredIndexes();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDerivedIndexes()
+ => GetDerivedIndexes();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyEntityType.GetIndexes()
=> GetIndexes();
///
@@ -4009,6 +4249,16 @@ IEnumerable IMutableEntityType.GetIndexes()
IEnumerable IConventionEntityType.GetIndexes()
=> GetIndexes();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetIndexes()
+ => GetIndexes();
+
///
/// 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
@@ -4070,7 +4320,17 @@ IMutableProperty IMutableEntityType.AddProperty(string name, Type propertyType,
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IProperty? IEntityType.FindProperty(string name)
+ IProperty? IEntityType.FindDeclaredProperty(string name)
+ => FindDeclaredProperty(name);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IReadOnlyProperty? IReadOnlyEntityType.FindProperty(string name)
=> FindProperty(name);
///
@@ -4100,7 +4360,27 @@ IMutableProperty IMutableEntityType.AddProperty(string name, Type propertyType,
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetProperties()
+ IProperty? IEntityType.FindProperty(string name)
+ => FindProperty(name);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredProperties()
+ => GetDeclaredProperties();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyEntityType.GetProperties()
=> GetProperties();
///
@@ -4123,6 +4403,36 @@ IEnumerable IMutableEntityType.GetProperties()
IEnumerable IConventionEntityType.GetProperties()
=> GetProperties();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetProperties()
+ => GetProperties();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetForeignKeyProperties()
+ => ForeignKeyProperties;
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetValueGeneratingProperties()
+ => ValueGeneratingProperties;
+
///
/// 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
@@ -4170,7 +4480,7 @@ IConventionServiceProperty IConventionEntityType.AddServiceProperty(MemberInfo m
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IServiceProperty? IEntityType.FindServiceProperty(string name)
+ IReadOnlyServiceProperty? IReadOnlyEntityType.FindServiceProperty(string name)
=> FindServiceProperty(name);
///
@@ -4200,7 +4510,27 @@ IConventionServiceProperty IConventionEntityType.AddServiceProperty(MemberInfo m
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- IEnumerable IEntityType.GetServiceProperties()
+ IServiceProperty? IEntityType.FindServiceProperty(string name)
+ => FindServiceProperty(name);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetDeclaredServiceProperties()
+ => GetDeclaredServiceProperties();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyEntityType.GetServiceProperties()
=> GetServiceProperties();
///
@@ -4223,6 +4553,16 @@ IEnumerable IMutableEntityType.GetServiceProperties()
IEnumerable IConventionEntityType.GetServiceProperties()
=> GetServiceProperties();
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IEntityType.GetServiceProperties()
+ => GetServiceProperties();
+
///
/// 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
diff --git a/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs b/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs
index 0e4315b4d3a..0999cfc9a8d 100644
--- a/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs
+++ b/src/EFCore/Metadata/Internal/EntityTypeExtensions.cs
@@ -34,7 +34,7 @@ public static class EntityTypeExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static MemberInfo GetNavigationMemberInfo(
- [NotNull] this IEntityType entityType,
+ [NotNull] this IReadOnlyEntityType entityType,
[NotNull] string navigationName)
{
var memberInfo = entityType.ClrType.GetMembersInHierarchy(navigationName).FirstOrDefault();
@@ -54,7 +54,7 @@ public static MemberInfo GetNavigationMemberInfo(
/// 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 IForeignKey? FindDeclaredOwnership([NotNull] this IEntityType entityType)
+ public static IReadOnlyForeignKey? FindDeclaredOwnership([NotNull] this IReadOnlyEntityType entityType)
=> ((EntityType)entityType).FindDeclaredOwnership();
///
@@ -63,7 +63,7 @@ public static MemberInfo GetNavigationMemberInfo(
/// 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 IEntityType? FindInOwnershipPath([NotNull] this IEntityType entityType, [NotNull] Type targetType)
+ public static IReadOnlyEntityType? FindInOwnershipPath([NotNull] this IReadOnlyEntityType entityType, [NotNull] Type targetType)
{
if (entityType.ClrType == targetType)
{
@@ -93,7 +93,7 @@ public static MemberInfo GetNavigationMemberInfo(
/// 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 bool IsInOwnershipPath([NotNull] this IEntityType entityType, [NotNull] Type targetType)
+ public static bool IsInOwnershipPath([NotNull] this IReadOnlyEntityType entityType, [NotNull] Type targetType)
=> entityType.FindInOwnershipPath(targetType) != null;
///
@@ -103,7 +103,7 @@ public static bool IsInOwnershipPath([NotNull] this IEntityType entityType, [Not
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[DebuggerStepThrough]
- public static string GetOwnedName([NotNull] this ITypeBase type, [NotNull] string simpleName, [NotNull] string ownershipNavigation)
+ public static string GetOwnedName([NotNull] this IReadOnlyTypeBase type, [NotNull] string simpleName, [NotNull] string ownershipNavigation)
=> type.Name + "." + ownershipNavigation + "#" + simpleName;
///
@@ -112,7 +112,7 @@ public static string GetOwnedName([NotNull] this ITypeBase type, [NotNull] strin
/// 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 bool UseEagerSnapshots([NotNull] this IEntityType entityType)
+ public static bool UseEagerSnapshots([NotNull] this IReadOnlyEntityType entityType)
{
var changeTrackingStrategy = entityType.GetChangeTrackingStrategy();
@@ -230,7 +230,7 @@ public static PropertyCounts CalculateCounts([NotNull] this EntityType entityTyp
index: navigationIndex++,
originalValueIndex: -1,
shadowIndex: navigation.IsShadowProperty() ? shadowIndex++ : -1,
- relationshipIndex: ((INavigationBase)navigation).IsCollection && isNotifying ? -1 : relationshipIndex++,
+ relationshipIndex: ((IReadOnlyNavigationBase)navigation).IsCollection && isNotifying ? -1 : relationshipIndex++,
storeGenerationIndex: -1);
navigation.PropertyIndexes = indexes;
@@ -275,24 +275,6 @@ public static Func GetInstanceFactory([NotNull]
public static Func GetEmptyShadowValuesFactory([NotNull] this IEntityType entityType)
=> entityType.AsEntityType().EmptyShadowValuesFactory;
- ///
- /// 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 IReadOnlyList GetPropagatingProperties([NotNull] this IEntityType entityType)
- => entityType.AsEntityType().PropagatingProperties;
-
- ///
- /// 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 IReadOnlyList GetGeneratingProperties([NotNull] this IEntityType entityType)
- => entityType.AsEntityType().GeneratingProperties;
-
///
/// 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
@@ -300,7 +282,7 @@ public static IReadOnlyList GetGeneratingProperties([NotNull] this IE
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static EntityType? LeastDerivedType([NotNull] this EntityType entityType, [NotNull] EntityType otherEntityType)
- => (EntityType?)((IEntityType)entityType).LeastDerivedType(otherEntityType);
+ => (EntityType?)((IReadOnlyEntityType)entityType).LeastDerivedType(otherEntityType);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -308,7 +290,7 @@ public static IReadOnlyList GetGeneratingProperties([NotNull] this IE
/// 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 IKey? FindDeclaredPrimaryKey([NotNull] this IEntityType entityType)
+ public static IReadOnlyKey? FindDeclaredPrimaryKey([NotNull] this IReadOnlyEntityType entityType)
=> entityType.BaseType == null ? entityType.FindPrimaryKey() : null;
///
@@ -317,8 +299,8 @@ public static IReadOnlyList GetGeneratingProperties([NotNull] this IE
/// 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 IEnumerable FindDerivedNavigations(
- [NotNull] this IEntityType entityType,
+ public static IEnumerable FindDerivedNavigations(
+ [NotNull] this IReadOnlyEntityType entityType,
[NotNull] string navigationName)
=> entityType.GetDerivedTypes().SelectMany(
et => et.GetDeclaredNavigations().Where(navigation => navigationName == navigation.Name));
@@ -329,7 +311,7 @@ public static IEnumerable FindDerivedNavigations(
/// 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 IEnumerable GetDerivedNavigations([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDerivedNavigations([NotNull] this IEntityType entityType)
=> entityType.AsEntityType().GetDerivedNavigations();
///
@@ -338,7 +320,7 @@ public static IEnumerable GetDerivedNavigations([NotNull] this IEnti
/// 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 IEnumerable GetDerivedSkipNavigations([NotNull] this IEntityType entityType)
+ public static IEnumerable GetDerivedSkipNavigations([NotNull] this IEntityType entityType)
=> entityType.AsEntityType().GetDerivedSkipNavigations();
///
@@ -357,49 +339,8 @@ public static IEnumerable GetPropertiesAndNavigations(
/// 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 IEnumerable GetNotificationProperties(
- [NotNull] this IEntityType entityType,
- [CanBeNull] string? propertyName)
- {
- if (string.IsNullOrEmpty(propertyName))
- {
- foreach (var property in entityType.GetProperties()
- .Where(p => p.GetAfterSaveBehavior() == PropertySaveBehavior.Save))
- {
- yield return property;
- }
-
- foreach (var navigation in entityType.GetNavigations())
- {
- yield return navigation;
- }
-
- foreach (var navigation in entityType.GetSkipNavigations())
- {
- yield return navigation;
- }
- }
- else
- {
- // ReSharper disable once AssignNullToNotNullAttribute
- var property = entityType.FindProperty(propertyName)
- ?? entityType.FindNavigation(propertyName)
- ?? (IPropertyBase?)entityType.FindSkipNavigation(propertyName);
-
- if (property != null)
- {
- yield return property;
- }
- }
- }
-
- ///
- /// 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 IProperty CheckPropertyBelongsToType([NotNull] this IEntityType entityType, [NotNull] IProperty property)
+ public static IProperty CheckPropertyBelongsToType(
+ [NotNull] this IEntityType entityType, [NotNull] IProperty property)
{
Check.NotNull(property, nameof(property));
@@ -418,33 +359,7 @@ public static IProperty CheckPropertyBelongsToType([NotNull] this IEntityType en
/// 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 EntityType AsEntityType([NotNull] this IEntityType entityType, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(entityType, methodName);
-
-
-
- ///
- /// Try to find the name of the type that has a different namespace from your entity types
- ///
- ///
- /// model Of your context to find entities
- ///
- ///
- /// A Type that you think have a different namespace and exists in your entity types
- ///
- ///
- /// the name with different namespace found
- ///
- public static string? FindSameTypeNameWithDifferentNamespace([NotNull] this IModel model, [NotNull] Type type)
- {
- //try to find the same name of the entity with type to throw a specific exception
- return model.GetEntityTypes()
- //check the short names are equals because the namespaces are not equaled we need to check just names are equals
- .Where(x => x.ClrType.DisplayName(false) == type.DisplayName(false))
- //select the full name of type because we need to show the developer a type with the full name
- .Select(x => x.ClrType.DisplayName())
- //select one of them to show the developer
- .FirstOrDefault();
- }
+ public static EntityType AsEntityType([NotNull] this IReadOnlyEntityType entityType, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(entityType, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/EntityTypeParameterBindingFactory.cs b/src/EFCore/Metadata/Internal/EntityTypeParameterBindingFactory.cs
index b0a5e464035..10d65369dbb 100644
--- a/src/EFCore/Metadata/Internal/EntityTypeParameterBindingFactory.cs
+++ b/src/EFCore/Metadata/Internal/EntityTypeParameterBindingFactory.cs
@@ -43,7 +43,8 @@ public virtual bool CanBind(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual ParameterBinding Bind(IMutableEntityType entityType, Type parameterType, string parameterName)
- => new EntityTypeParameterBinding(entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
+ => new EntityTypeParameterBinding(
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -55,6 +56,7 @@ public virtual ParameterBinding Bind(
IConventionEntityType entityType,
Type parameterType,
string parameterName)
- => new EntityTypeParameterBinding(entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
+ => new EntityTypeParameterBinding(
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == parameterType));
}
}
diff --git a/src/EFCore/Metadata/Internal/ForeignKey.cs b/src/EFCore/Metadata/Internal/ForeignKey.cs
index 54d9f35b66f..06bfbdc0045 100644
--- a/src/EFCore/Metadata/Internal/ForeignKey.cs
+++ b/src/EFCore/Metadata/Internal/ForeignKey.cs
@@ -12,7 +12,6 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Utilities;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -24,7 +23,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 ForeignKey : ConventionAnnotatable, IMutableForeignKey, IConventionForeignKey
+ public class ForeignKey : ConventionAnnotatable, IMutableForeignKey, IConventionForeignKey, IForeignKey
{
private DeleteBehavior? _deleteBehavior;
private bool? _isUnique;
@@ -152,7 +151,7 @@ public virtual void SetRemovedFromModel()
/// 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.
///
- protected override bool IsReadOnly => DeclaringEntityType.Model.IsModelReadOnly;
+ public override bool IsReadOnly => DeclaringEntityType.Model.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -849,7 +848,7 @@ public virtual void UpdateIsOwnershipConfigurationSource(ConfigurationSource con
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindNavigationsFromInHierarchy([NotNull] EntityType entityType)
- => ((IForeignKey)this).FindNavigationsFromInHierarchy(entityType).Cast();
+ => ((IReadOnlyForeignKey)this).FindNavigationsFromInHierarchy(entityType).Cast();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -858,7 +857,7 @@ public virtual IEnumerable FindNavigationsFromInHierarchy([NotNull]
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual IEnumerable FindNavigationsTo([NotNull] EntityType entityType)
- => ((IForeignKey)this).FindNavigationsTo(entityType).Cast();
+ => ((IReadOnlyForeignKey)this).FindNavigationsTo(entityType).Cast();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -867,7 +866,7 @@ public virtual IEnumerable FindNavigationsTo([NotNull] EntityType en
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public virtual EntityType ResolveOtherEntityType([NotNull] EntityType entityType)
- => (EntityType)((IForeignKey)this).GetRelatedEntityType(entityType);
+ => (EntityType)((IReadOnlyForeignKey)this).GetRelatedEntityType(entityType);
// Note: This is set and used only by IdentityMapFactoryFactory, which ensures thread-safety
///
@@ -931,7 +930,7 @@ public virtual Func DependentsMapFactory
/// 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.
///
- IReadOnlyList IForeignKey.Properties
+ IReadOnlyList IReadOnlyForeignKey.Properties
{
[DebuggerStepThrough]
get => Properties;
@@ -943,7 +942,7 @@ IReadOnlyList IForeignKey.Properties
/// 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.
///
- IKey IForeignKey.PrincipalKey
+ IReadOnlyKey IReadOnlyForeignKey.PrincipalKey
{
[DebuggerStepThrough]
get => PrincipalKey;
@@ -955,7 +954,7 @@ IKey IForeignKey.PrincipalKey
/// 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 IForeignKey.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyForeignKey.DeclaringEntityType
{
[DebuggerStepThrough]
get => DeclaringEntityType;
@@ -967,7 +966,7 @@ IEntityType IForeignKey.DeclaringEntityType
/// 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 IForeignKey.PrincipalEntityType
+ IReadOnlyEntityType IReadOnlyForeignKey.PrincipalEntityType
{
[DebuggerStepThrough]
get => PrincipalEntityType;
@@ -979,7 +978,7 @@ IEntityType IForeignKey.PrincipalEntityType
/// 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.
///
- INavigation? IForeignKey.DependentToPrincipal
+ IReadOnlyNavigation? IReadOnlyForeignKey.DependentToPrincipal
{
[DebuggerStepThrough]
get => DependentToPrincipal;
@@ -991,7 +990,7 @@ IEntityType IForeignKey.PrincipalEntityType
/// 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.
///
- INavigation? IForeignKey.PrincipalToDependent
+ IReadOnlyNavigation? IReadOnlyForeignKey.PrincipalToDependent
{
[DebuggerStepThrough]
get => PrincipalToDependent;
@@ -1133,6 +1132,18 @@ IConventionEntityType IConventionForeignKey.DeclaringEntityType
get => 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.
+ ///
+ IEntityType IForeignKey.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => 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
@@ -1145,6 +1156,18 @@ IConventionEntityType IConventionForeignKey.PrincipalEntityType
get => PrincipalEntityType;
}
+ ///
+ /// 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 IForeignKey.PrincipalEntityType
+ {
+ [DebuggerStepThrough]
+ get => PrincipalEntityType;
+ }
+
///
/// 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
@@ -1157,6 +1180,18 @@ IConventionKey IConventionForeignKey.PrincipalKey
get => PrincipalKey;
}
+ ///
+ /// 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.
+ ///
+ IKey IForeignKey.PrincipalKey
+ {
+ [DebuggerStepThrough]
+ get => PrincipalKey;
+ }
+
///
/// 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
@@ -1169,6 +1204,18 @@ IReadOnlyList IConventionForeignKey.Properties
get => Properties;
}
+ ///
+ /// 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.
+ ///
+ IReadOnlyList IForeignKey.Properties
+ {
+ [DebuggerStepThrough]
+ get => Properties;
+ }
+
///
/// 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
@@ -1181,6 +1228,18 @@ IReadOnlyList IConventionForeignKey.Properties
get => DependentToPrincipal;
}
+ ///
+ /// 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.
+ ///
+ INavigation? IForeignKey.DependentToPrincipal
+ {
+ [DebuggerStepThrough]
+ get => DependentToPrincipal;
+ }
+
///
/// 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
@@ -1193,6 +1252,18 @@ IReadOnlyList IConventionForeignKey.Properties
get => PrincipalToDependent;
}
+ ///
+ /// 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.
+ ///
+ INavigation? IForeignKey.PrincipalToDependent
+ {
+ [DebuggerStepThrough]
+ get => PrincipalToDependent;
+ }
+
///
/// 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
@@ -1249,7 +1320,7 @@ IReadOnlyList IConventionForeignKey.SetProperties(
///
[DebuggerStepThrough]
- IEnumerable IForeignKey.GetReferencingSkipNavigations()
+ IEnumerable IReadOnlyForeignKey.GetReferencingSkipNavigations()
=> GetReferencingSkipNavigations();
///
@@ -1366,8 +1437,8 @@ public static bool AreCompatible(
[NotNull] EntityType dependentEntityType,
[CanBeNull] MemberInfo? navigationToPrincipal,
[CanBeNull] MemberInfo? navigationToDependent,
- [CanBeNull] IReadOnlyList? dependentProperties,
- [CanBeNull] IReadOnlyList? principalProperties,
+ [CanBeNull] IReadOnlyList? dependentProperties,
+ [CanBeNull] IReadOnlyList? principalProperties,
bool? unique,
bool shouldThrow)
{
@@ -1415,10 +1486,10 @@ public static bool AreCompatible(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static bool AreCompatible(
- [NotNull] IReadOnlyList principalProperties,
- [NotNull] IReadOnlyList dependentProperties,
- [NotNull] IEntityType principalEntityType,
- [NotNull] IEntityType dependentEntityType,
+ [NotNull] IReadOnlyList principalProperties,
+ [NotNull] IReadOnlyList dependentProperties,
+ [NotNull] IReadOnlyEntityType principalEntityType,
+ [NotNull] IReadOnlyEntityType dependentEntityType,
bool shouldThrow)
{
Check.NotNull(principalProperties, nameof(principalProperties));
@@ -1460,13 +1531,13 @@ public static bool AreCompatible(
}
private static bool ArePropertyCountsEqual(
- IReadOnlyList principalProperties,
- IReadOnlyList dependentProperties)
+ IReadOnlyList principalProperties,
+ IReadOnlyList dependentProperties)
=> principalProperties.Count == dependentProperties.Count;
private static bool ArePropertyTypesCompatible(
- IReadOnlyList principalProperties,
- IReadOnlyList dependentProperties)
+ IReadOnlyList principalProperties,
+ IReadOnlyList dependentProperties)
=> principalProperties.Select(p => p.ClrType.UnwrapNullableType()).SequenceEqual(
dependentProperties.Select(p => p.ClrType.UnwrapNullableType()));
}
diff --git a/src/EFCore/Metadata/Internal/ForeignKeyExtensions.cs b/src/EFCore/Metadata/Internal/ForeignKeyExtensions.cs
index 0cce91d9e28..e797b11735c 100644
--- a/src/EFCore/Metadata/Internal/ForeignKeyExtensions.cs
+++ b/src/EFCore/Metadata/Internal/ForeignKeyExtensions.cs
@@ -26,7 +26,7 @@ public static class ForeignKeyExtensions
/// 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 bool IsSelfReferencing([NotNull] this IForeignKey foreignKey)
+ public static bool IsSelfReferencing([NotNull] this IReadOnlyForeignKey foreignKey)
=> foreignKey.DeclaringEntityType == foreignKey.PrincipalEntityType;
///
@@ -35,7 +35,7 @@ public static bool IsSelfReferencing([NotNull] this IForeignKey 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 static IEnumerable GetNavigations([NotNull] this IForeignKey foreignKey)
+ public static IEnumerable GetNavigations([NotNull] this IReadOnlyForeignKey foreignKey)
{
if (foreignKey.PrincipalToDependent != null)
{
@@ -54,9 +54,9 @@ public static IEnumerable GetNavigations([NotNull] this IForeignKey
/// 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 IEnumerable FindNavigationsFrom(
- [NotNull] this IForeignKey foreignKey,
- [NotNull] IEntityType entityType)
+ public static IEnumerable FindNavigationsFrom(
+ [NotNull] this IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyEntityType entityType)
{
if (foreignKey.DeclaringEntityType != entityType
&& foreignKey.PrincipalEntityType != entityType)
@@ -79,9 +79,9 @@ public static IEnumerable FindNavigationsFrom(
/// 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 IEnumerable FindNavigationsFromInHierarchy(
- [NotNull] this IForeignKey foreignKey,
- [NotNull] IEntityType entityType)
+ public static IEnumerable FindNavigationsFromInHierarchy(
+ [NotNull] this IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyEntityType entityType)
{
if (!foreignKey.DeclaringEntityType.IsAssignableFrom(entityType)
&& !foreignKey.PrincipalEntityType.IsAssignableFrom(entityType))
@@ -105,7 +105,8 @@ public static IEnumerable FindNavigationsFromInHierarchy(
/// 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 IEnumerable FindNavigationsTo([NotNull] this IForeignKey foreignKey, [NotNull] IEntityType entityType)
+ public static IEnumerable FindNavigationsTo(
+ [NotNull] this IReadOnlyForeignKey foreignKey, [NotNull] IReadOnlyEntityType entityType)
{
if (foreignKey.DeclaringEntityType != entityType
&& foreignKey.PrincipalEntityType != entityType)
@@ -128,9 +129,9 @@ public static IEnumerable FindNavigationsTo([NotNull] this IForeign
/// 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 IEnumerable FindNavigationsToInHierarchy(
- [NotNull] this IForeignKey foreignKey,
- [NotNull] IEntityType entityType)
+ public static IEnumerable FindNavigationsToInHierarchy(
+ [NotNull] this IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyEntityType entityType)
{
if (!foreignKey.DeclaringEntityType.IsAssignableFrom(entityType)
&& !foreignKey.PrincipalEntityType.IsAssignableFrom(entityType))
@@ -147,8 +148,8 @@ public static IEnumerable FindNavigationsToInHierarchy(
: foreignKey.FindNavigations(foreignKey.PrincipalEntityType.IsAssignableFrom(entityType));
}
- private static IEnumerable FindNavigations(
- this IForeignKey foreignKey,
+ private static IEnumerable FindNavigations(
+ this IReadOnlyForeignKey foreignKey,
bool toPrincipal)
{
if (toPrincipal)
@@ -174,9 +175,9 @@ private static IEnumerable FindNavigations(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[Obsolete]
- public static IEntityType ResolveOtherEntityTypeInHierarchy(
- [NotNull] this IForeignKey foreignKey,
- [NotNull] IEntityType entityType)
+ public static IReadOnlyEntityType ResolveOtherEntityTypeInHierarchy(
+ [NotNull] this IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyEntityType entityType)
{
if (!foreignKey.DeclaringEntityType.IsAssignableFrom(entityType)
&& !foreignKey.PrincipalEntityType.IsAssignableFrom(entityType))
@@ -211,7 +212,7 @@ public static IEntityType ResolveOtherEntityTypeInHierarchy(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[Obsolete]
- public static IEntityType ResolveEntityTypeInHierarchy([NotNull] this IForeignKey foreignKey, [NotNull] IEntityType entityType)
+ public static IReadOnlyEntityType ResolveEntityTypeInHierarchy([NotNull] this IReadOnlyForeignKey foreignKey, [NotNull] IReadOnlyEntityType entityType)
{
if (!foreignKey.DeclaringEntityType.IsAssignableFrom(entityType)
&& !foreignKey.PrincipalEntityType.IsAssignableFrom(entityType))
@@ -244,7 +245,7 @@ public static IEntityType ResolveEntityTypeInHierarchy([NotNull] this IForeignKe
/// 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 IDependentsMap CreateDependentsMapFactory([NotNull] this IForeignKey foreignKey)
+ public static IDependentsMap CreateDependentsMapFactory([NotNull] this IReadOnlyForeignKey foreignKey)
=> foreignKey.AsForeignKey().DependentsMapFactory();
///
@@ -253,7 +254,7 @@ public static IDependentsMap CreateDependentsMapFactory([NotNull] this IForeignK
/// 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 ForeignKey AsForeignKey([NotNull] this IForeignKey foreignKey, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(foreignKey, methodName);
+ public static ForeignKey AsForeignKey([NotNull] this IReadOnlyForeignKey foreignKey, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(foreignKey, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/Index.cs b/src/EFCore/Metadata/Internal/Index.cs
index 24634905937..78fb778c0a9 100644
--- a/src/EFCore/Metadata/Internal/Index.cs
+++ b/src/EFCore/Metadata/Internal/Index.cs
@@ -23,7 +23,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 Index : ConventionAnnotatable, IMutableIndex, IConventionIndex
+ public class Index : ConventionAnnotatable, IMutableIndex, IConventionIndex, IIndex
{
private bool? _isUnique;
private InternalIndexBuilder? _builder;
@@ -133,7 +133,7 @@ public virtual void SetRemovedFromModel()
/// 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.
///
- protected override bool IsReadOnly => DeclaringEntityType.Model.IsModelReadOnly;
+ public override bool IsReadOnly => DeclaringEntityType.Model.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -261,7 +261,7 @@ 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.
///
- IReadOnlyList IIndex.Properties
+ IReadOnlyList IReadOnlyIndex.Properties
{
[DebuggerStepThrough] get => Properties;
}
@@ -272,7 +272,7 @@ IReadOnlyList IIndex.Properties
/// 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 IIndex.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyIndex.DeclaringEntityType
{
[DebuggerStepThrough] get => DeclaringEntityType;
}
@@ -332,6 +332,18 @@ IReadOnlyList IConventionIndex.Properties
[DebuggerStepThrough] get => Properties;
}
+ ///
+ /// 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.
+ ///
+ IReadOnlyList IIndex.Properties
+ {
+ [DebuggerStepThrough]
+ get => Properties;
+ }
+
///
/// 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
@@ -343,6 +355,18 @@ IConventionEntityType IConventionIndex.DeclaringEntityType
[DebuggerStepThrough] get => 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.
+ ///
+ IEntityType IIndex.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => 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
diff --git a/src/EFCore/Metadata/Internal/IndexExtensions.cs b/src/EFCore/Metadata/Internal/IndexExtensions.cs
index d459e9479e5..f99b66dc1e3 100644
--- a/src/EFCore/Metadata/Internal/IndexExtensions.cs
+++ b/src/EFCore/Metadata/Internal/IndexExtensions.cs
@@ -22,7 +22,7 @@ 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 IIndex index, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(index, methodName);
+ public static Index AsIndex([NotNull] this IReadOnlyIndex index, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(index, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
index d2fad8f4310..737f6a58531 100644
--- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
@@ -1500,7 +1500,7 @@ public virtual bool CanSetDefiningQuery([CanBeNull] LambdaExpression? query, Con
&& navigationToDependent.GetConfigurationSource() == ConfigurationSource.Explicit)
{
var baseProperty = baseEntityType.FindMembersInHierarchy(navigationToDependent.Name).Single();
- if (!(baseProperty is INavigation))
+ if (!(baseProperty is IReadOnlyNavigation))
{
throw new InvalidOperationException(
CoreStrings.DuplicatePropertiesOnBase(
@@ -1881,25 +1881,25 @@ public virtual bool CanSetBaseType([CanBeNull] EntityType? baseEntityType, Confi
if (derivedMember.GetConfigurationSource() == ConfigurationSource.Explicit
&& baseMembers.TryGetValue(derivedMember.Name, out var baseMember))
{
- if (derivedMember is IProperty)
+ if (derivedMember is IReadOnlyProperty)
{
- return baseMember is IProperty;
+ return baseMember is IReadOnlyProperty;
}
- if (derivedMember is INavigation derivedNavigation)
+ if (derivedMember is IReadOnlyNavigation derivedNavigation)
{
- return baseMember is INavigation baseNavigation
+ return baseMember is IReadOnlyNavigation baseNavigation
&& derivedNavigation.TargetEntityType == baseNavigation.TargetEntityType;
}
- if (derivedMember is IServiceProperty)
+ if (derivedMember is IReadOnlyServiceProperty)
{
- return baseMember is IServiceProperty;
+ return baseMember is IReadOnlyServiceProperty;
}
- if (derivedMember is ISkipNavigation derivedSkipNavigation)
+ if (derivedMember is IReadOnlySkipNavigation derivedSkipNavigation)
{
- return baseMember is ISkipNavigation baseSkipNavigation
+ return baseMember is IReadOnlySkipNavigation baseSkipNavigation
&& derivedSkipNavigation.TargetEntityType == baseSkipNavigation.TargetEntityType;
}
}
@@ -3289,7 +3289,7 @@ public virtual bool RemoveNonOwnershipRelationships([CanBeNull] ForeignKey? owne
return true;
}
- private bool Contains(IForeignKey? inheritedFk, IForeignKey derivedFk)
+ private bool Contains(IReadOnlyForeignKey? inheritedFk, IReadOnlyForeignKey derivedFk)
=> inheritedFk != null
&& inheritedFk.PrincipalEntityType.IsAssignableFrom(derivedFk.PrincipalEntityType)
&& PropertyListComparer.Instance.Equals(inheritedFk.Properties, derivedFk.Properties);
@@ -4314,7 +4314,7 @@ public virtual bool CanSetPropertyAccessMode(PropertyAccessMode? propertyAccessM
private InternalPropertyBuilder? GetOrCreateDiscriminatorProperty(Type? type, string? name, ConfigurationSource configurationSource)
{
- var discriminatorProperty = ((IEntityType)Metadata).GetDiscriminatorProperty();
+ var discriminatorProperty = ((IReadOnlyEntityType)Metadata).GetDiscriminatorProperty();
if ((name != null && discriminatorProperty?.Name != name)
|| (type != null && discriminatorProperty?.ClrType != type))
{
@@ -4388,7 +4388,7 @@ public virtual bool CanSetPropertyAccessMode(PropertyAccessMode? propertyAccessM
private void RemoveUnusedDiscriminatorProperty(Property? newDiscriminatorProperty, ConfigurationSource configurationSource)
{
- var oldDiscriminatorProperty = ((IEntityType)Metadata).GetDiscriminatorProperty() as Property;
+ var oldDiscriminatorProperty = ((IReadOnlyEntityType)Metadata).GetDiscriminatorProperty() as Property;
if (oldDiscriminatorProperty?.IsInModel == true
&& oldDiscriminatorProperty != newDiscriminatorProperty)
{
@@ -4412,10 +4412,10 @@ private void RemoveUnusedDiscriminatorProperty(Property? newDiscriminatorPropert
public virtual bool CanSetDiscriminator([CanBeNull] string? name, [CanBeNull] Type? type, ConfigurationSource configurationSource)
=> name == null && type == null
? CanRemoveDiscriminator(configurationSource)
- : CanSetDiscriminator(((IEntityType)Metadata).GetDiscriminatorProperty(), name, type, configurationSource);
+ : CanSetDiscriminator(((IReadOnlyEntityType)Metadata).GetDiscriminatorProperty(), name, type, configurationSource);
private bool CanSetDiscriminator(
- IProperty? discriminatorProperty,
+ IReadOnlyProperty? discriminatorProperty,
string? name,
Type? discriminatorType,
ConfigurationSource configurationSource)
@@ -5114,7 +5114,7 @@ bool IConventionEntityTypeBuilder.CanHaveSkipNavigation(string skipNavigationNam
///
[DebuggerStepThrough]
IConventionEntityTypeBuilder? IConventionEntityTypeBuilder.HasNoSkipNavigation(
- ISkipNavigation skipNavigation,
+ IReadOnlySkipNavigation skipNavigation,
bool fromDataAnnotation)
=> HasNoSkipNavigation(
(SkipNavigation)skipNavigation,
@@ -5122,7 +5122,7 @@ bool IConventionEntityTypeBuilder.CanHaveSkipNavigation(string skipNavigationNam
///
[DebuggerStepThrough]
- bool IConventionEntityTypeBuilder.CanRemoveSkipNavigation(ISkipNavigation skipNavigation, bool fromDataAnnotation)
+ bool IConventionEntityTypeBuilder.CanRemoveSkipNavigation(IReadOnlySkipNavigation skipNavigation, bool fromDataAnnotation)
=> CanRemoveSkipNavigation(
(SkipNavigation)skipNavigation,
fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
diff --git a/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs b/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs
index 024c8212f00..fce24ef1d33 100644
--- a/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalForeignKeyBuilder.cs
@@ -1835,7 +1835,7 @@ public virtual bool CanInvert(
public virtual bool CanSetForeignKey([CanBeNull] IReadOnlyList? propertyNames, ConfigurationSource? configurationSource)
{
if (propertyNames is not null
- && Metadata.DeclaringEntityType.FindProperties(propertyNames) is IReadOnlyList properties)
+ && ((IReadOnlyEntityType)Metadata.DeclaringEntityType).FindProperties(propertyNames) is IReadOnlyList properties)
{
return CanSetForeignKey(
properties,
@@ -1861,7 +1861,7 @@ public virtual bool CanSetForeignKey([CanBeNull] IReadOnlyList? proper
out _);
private bool CanSetForeignKey(
- IReadOnlyList? properties,
+ IReadOnlyList? properties,
EntityType? dependentEntityType,
ConfigurationSource? configurationSource,
bool overrideSameSource = true)
@@ -1873,7 +1873,7 @@ private bool CanSetForeignKey(
overrideSameSource);
private bool CanSetForeignKey(
- IReadOnlyList? properties,
+ IReadOnlyList? properties,
EntityType? dependentEntityType,
ConfigurationSource? configurationSource,
out bool resetPrincipalKey,
@@ -1893,7 +1893,7 @@ private bool CanSetForeignKey(
}
private bool CanSetForeignKey(
- IReadOnlyList? properties,
+ IReadOnlyList? properties,
EntityType? dependentEntityType,
IReadOnlyList principalKeyProperties,
EntityType principalEntityType,
@@ -2062,7 +2062,7 @@ private bool CanSetForeignKey(
public virtual bool CanSetPrincipalKey([CanBeNull] IReadOnlyList? propertyNames, ConfigurationSource? configurationSource)
{
if (propertyNames is not null
- && Metadata.PrincipalEntityType.FindProperties(propertyNames) is IReadOnlyList properties)
+ && ((IReadOnlyEntityType)Metadata.PrincipalEntityType).FindProperties(propertyNames) is IReadOnlyList properties)
{
return CanSetPrincipalKey(
properties,
@@ -2088,7 +2088,7 @@ public virtual bool CanSetPrincipalKey([CanBeNull] IReadOnlyList? prop
out _);
private bool CanSetPrincipalKey(
- IReadOnlyList? properties,
+ IReadOnlyList? properties,
ConfigurationSource? configurationSource,
out bool resetDependent,
out IReadOnlyList? oldNameDependentProperties)
@@ -2842,9 +2842,9 @@ private InternalForeignKeyBuilder MergeFacetsFrom(Navigation newNavigation, Navi
var oldIsEagerLoadedConfigurationSource = ((IConventionNavigation)oldNavigation).GetIsEagerLoadedConfigurationSource();
if (oldIsEagerLoadedConfigurationSource.HasValue
- && builder.CanSetAutoInclude(((INavigation)oldNavigation).IsEagerLoaded, oldIsEagerLoadedConfigurationSource.Value))
+ && builder.CanSetAutoInclude(((IReadOnlyNavigation)oldNavigation).IsEagerLoaded, oldIsEagerLoadedConfigurationSource.Value))
{
- builder = builder.AutoInclude(((INavigation)oldNavigation).IsEagerLoaded, oldIsEagerLoadedConfigurationSource.Value)!;
+ builder = builder.AutoInclude(((IReadOnlyNavigation)oldNavigation).IsEagerLoaded, oldIsEagerLoadedConfigurationSource.Value)!;
}
return builder.Metadata.ForeignKey.Builder;
@@ -3361,7 +3361,7 @@ private InternalForeignKeyBuilder MergeFacetsFrom(Navigation newNavigation, Navi
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static void ThrowForConflictingNavigation(
- [NotNull] IForeignKey foreignKey,
+ [NotNull] IReadOnlyForeignKey foreignKey,
[NotNull] string newInverseName,
bool newToPrincipal)
=> ThrowForConflictingNavigation(
@@ -3377,9 +3377,9 @@ public static void ThrowForConflictingNavigation(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static void ThrowForConflictingNavigation(
- [NotNull] IForeignKey foreignKey,
- [NotNull] IEntityType principalEntityType,
- [NotNull] IEntityType dependentEntityType,
+ [NotNull] IReadOnlyForeignKey foreignKey,
+ [NotNull] IReadOnlyEntityType principalEntityType,
+ [NotNull] IReadOnlyEntityType dependentEntityType,
[CanBeNull] string? navigationToDependent,
[CanBeNull] string? navigationToPrincipal)
=> throw new InvalidOperationException(
diff --git a/src/EFCore/Metadata/Internal/InternalPropertyBaseBuilder`.cs b/src/EFCore/Metadata/Internal/InternalPropertyBaseBuilder`.cs
index aebc7360351..b231a55940a 100644
--- a/src/EFCore/Metadata/Internal/InternalPropertyBaseBuilder`.cs
+++ b/src/EFCore/Metadata/Internal/InternalPropertyBaseBuilder`.cs
@@ -141,6 +141,6 @@ public virtual bool CanSetPropertyAccessMode(
PropertyAccessMode? propertyAccessMode,
ConfigurationSource? configurationSource)
=> configurationSource.Overrides(Metadata.GetPropertyAccessModeConfigurationSource())
- || ((IPropertyBase)Metadata).GetPropertyAccessMode() == propertyAccessMode;
+ || ((IReadOnlyPropertyBase)Metadata).GetPropertyAccessMode() == propertyAccessMode;
}
}
diff --git a/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs b/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs
index 39508db1351..a3ec56d2ddf 100644
--- a/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalPropertyBuilder.cs
@@ -550,7 +550,7 @@ public virtual bool CanSetValueComparer([CanBeNull] ValueComparer? comparer, Con
return true;
}
-
+
return Metadata[CoreAnnotationNames.ValueComparer] == comparer;
}
@@ -663,7 +663,7 @@ public virtual bool CanSetKeyValueComparer([CanBeNull] ValueComparer? comparer,
if (oldPropertyAccessModeConfigurationSource.HasValue)
{
newPropertyBuilder.UsePropertyAccessMode(
- ((IProperty)Metadata).GetPropertyAccessMode(), oldPropertyAccessModeConfigurationSource.Value);
+ ((IReadOnlyProperty)Metadata).GetPropertyAccessMode(), oldPropertyAccessModeConfigurationSource.Value);
}
var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource();
diff --git a/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs b/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
index c4dc527d156..096999b35db 100644
--- a/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
+++ b/src/EFCore/Metadata/Internal/InternalSkipNavigationBuilder.cs
@@ -298,7 +298,7 @@ public virtual bool CanSetInverse(
if (propertyAccessModeConfigurationSource.HasValue)
{
newSkipNavigationBuilder.UsePropertyAccessMode(
- ((ISkipNavigation)Metadata).GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value);
+ ((IReadOnlySkipNavigation)Metadata).GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value);
}
var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource();
diff --git a/src/EFCore/Metadata/Internal/Key.cs b/src/EFCore/Metadata/Internal/Key.cs
index ef434bbd69c..54a6f5f2d79 100644
--- a/src/EFCore/Metadata/Internal/Key.cs
+++ b/src/EFCore/Metadata/Internal/Key.cs
@@ -24,7 +24,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 Key : ConventionAnnotatable, IMutableKey, IConventionKey
+ public class Key : ConventionAnnotatable, IMutableKey, IConventionKey, IKey
{
private InternalKeyBuilder? _builder;
private ConfigurationSource _configurationSource;
@@ -105,7 +105,7 @@ public virtual void SetRemovedFromModel()
/// 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.
///
- protected override bool IsReadOnly => DeclaringEntityType.Model.IsModelReadOnly;
+ public override bool IsReadOnly => DeclaringEntityType.Model.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -216,7 +216,7 @@ 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.
///
- IReadOnlyList IKey.Properties
+ IReadOnlyList IReadOnlyKey.Properties
{
[DebuggerStepThrough] get => Properties;
}
@@ -227,7 +227,7 @@ IReadOnlyList IKey.Properties
/// 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 IKey.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyKey.DeclaringEntityType
{
[DebuggerStepThrough] get => DeclaringEntityType;
}
@@ -288,6 +288,18 @@ IReadOnlyList IConventionKey.Properties
[DebuggerStepThrough] get => Properties;
}
+ ///
+ /// 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.
+ ///
+ IReadOnlyList IKey.Properties
+ {
+ [DebuggerStepThrough]
+ get => Properties;
+ }
+
///
/// 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
@@ -298,5 +310,17 @@ IConventionEntityType IConventionKey.DeclaringEntityType
{
[DebuggerStepThrough] get => 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.
+ ///
+ IEntityType IKey.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => DeclaringEntityType;
+ }
}
}
diff --git a/src/EFCore/Metadata/Internal/KeyExtensions.cs b/src/EFCore/Metadata/Internal/KeyExtensions.cs
index 8eb6f5d3b37..bf1116fe0a7 100644
--- a/src/EFCore/Metadata/Internal/KeyExtensions.cs
+++ b/src/EFCore/Metadata/Internal/KeyExtensions.cs
@@ -24,7 +24,7 @@ public static class KeyExtensions
/// 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 Func GetIdentityMapFactory([NotNull] this IKey key)
+ public static Func GetIdentityMapFactory([NotNull] this IReadOnlyKey key)
=> key.AsKey().IdentityMapFactory;
///
@@ -33,7 +33,7 @@ public static Func GetIdentityMapFactory([NotNull] this IKey
/// 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 int IndexOf([NotNull] this IKey key, [NotNull] IProperty property)
+ public static int IndexOf([NotNull] this IReadOnlyKey key, [NotNull] IReadOnlyProperty property)
{
var index = 0;
for (; index < key.Properties.Count && key.Properties[index] != property; index++)
@@ -49,7 +49,7 @@ public static int IndexOf([NotNull] this IKey key, [NotNull] IProperty property)
/// 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 Key AsKey([NotNull] this IKey key, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(key, methodName);
+ public static Key AsKey([NotNull] this IReadOnlyKey key, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(key, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs
index f5286230636..2a73a1cb1fd 100644
--- a/src/EFCore/Metadata/Internal/Model.cs
+++ b/src/EFCore/Metadata/Internal/Model.cs
@@ -37,7 +37,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal
/// The implementation does not need to be thread-safe.
///
///
- public class Model : ConventionAnnotatable, IMutableModel, IConventionModel
+ public class Model : ConventionAnnotatable, IMutableModel, IConventionModel, IModel
{
///
/// The CLR type that is used for property bag entity types when no other type is specified.
@@ -118,12 +118,7 @@ public virtual ModelDependencies? ScopedModelDependencies
///
/// Indicates whether the model is read-only.
///
- protected override bool IsReadOnly => IsModelReadOnly;
-
- ///
- /// Indicates whether the model is read-only.
- ///
- public virtual bool IsModelReadOnly => _conventionDispatcher == null;
+ public override bool IsReadOnly => _conventionDispatcher == null;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -474,59 +469,6 @@ public virtual IReadOnlyCollection GetEntityTypes([NotNull] string n
: new[] { entityType };
}
- ///
- /// 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 IReadOnlyList FindLeastDerivedEntityTypes(
- [NotNull] Type type,
- [CanBeNull] Func? condition = null)
- {
- var derivedLevels = new Dictionary { [type] = 0 };
-
- var leastDerivedTypesGroups = GetEntityTypes()
- .GroupBy(t => GetDerivedLevel(t.ClrType, derivedLevels))
- .Where(g => g.Key != int.MaxValue)
- .OrderBy(g => g.Key);
-
- foreach (var leastDerivedTypes in leastDerivedTypesGroups)
- {
- if (condition == null)
- {
- return leastDerivedTypes.ToList();
- }
-
- var filteredTypes = leastDerivedTypes.Where(condition).ToList();
- if (filteredTypes.Count > 0)
- {
- return filteredTypes;
- }
- }
-
- return new List();
- }
-
- private static int GetDerivedLevel(Type? derivedType, Dictionary derivedLevels)
- {
- if (derivedType?.BaseType == null)
- {
- return int.MaxValue;
- }
-
- if (derivedLevels.TryGetValue(derivedType, out var level))
- {
- return level;
- }
-
- var baseType = derivedType.BaseType;
- level = GetDerivedLevel(baseType, derivedLevels);
- level += level == int.MaxValue ? 0 : 1;
- derivedLevels.Add(derivedType, level);
- return level;
- }
-
///
/// 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
@@ -893,13 +835,16 @@ public virtual IModel FinalizeModel()
EnsureMutable();
ConventionDispatcher.AssertNoScope();
- IModel? finalizedModel = ConventionDispatcher.OnModelFinalizing(Builder)?.Metadata;
- if (finalizedModel != null)
+ var finalizedModel = (IModel)ConventionDispatcher.OnModelFinalizing(Builder).Metadata;
+
+ finalizedModel = ConventionDispatcher.OnModelFinalized(finalizedModel);
+
+ if (finalizedModel is Model model)
{
- finalizedModel = ConventionDispatcher.OnModelFinalized(finalizedModel);
+ finalizedModel = model.MakeReadonly();
}
- return (finalizedModel as Model)?.MakeReadonly() ?? finalizedModel!;
+ return finalizedModel;
}
///
@@ -908,7 +853,7 @@ public virtual IModel FinalizeModel()
/// 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.
///
- private IModel MakeReadonly()
+ private Model MakeReadonly()
{
// ConventionDispatcher should never be accessed once the model is made read-only.
_conventionDispatcher = null;
@@ -961,17 +906,6 @@ public virtual bool SkipDetectChanges
public virtual object? RelationalModel
=> FindRuntimeAnnotation("Relational:RelationalModel");
- ///
- /// 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 DebugView DebugView
- => new(
- () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
- () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
-
///
/// The runtime service dependencies.
///
@@ -989,12 +923,15 @@ public virtual DebugView DebugView
}
///
- /// Set the runtime service dependencies.
+ /// 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.
///
- /// The runtime service dependencies.
- /// if the runtime service dependencies were set; otherwise.
- bool IModel.SetModelDependencies(SingletonModelDependencies modelDependencies)
- => Interlocked.CompareExchange(ref _modelDependencies, modelDependencies, null) == null;
+ public virtual DebugView DebugView
+ => new(
+ () => this.ToDebugString(MetadataDebugStringOptions.ShortDefault),
+ () => this.ToDebugString(MetadataDebugStringOptions.LongDefault));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1002,8 +939,11 @@ bool IModel.SetModelDependencies(SingletonModelDependencies modelDependencies)
/// 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? IModel.FindEntityType(string name)
- => FindEntityType(name);
+ IConventionModelBuilder IConventionModel.Builder
+ {
+ [DebuggerStepThrough]
+ get => Builder;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1011,8 +951,11 @@ bool IModel.SetModelDependencies(SingletonModelDependencies modelDependencies)
/// 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.
///
- IEnumerable IModel.GetEntityTypes()
- => GetEntityTypes();
+ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
+ {
+ [DebuggerStepThrough]
+ get => Builder;
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1020,7 +963,8 @@ IEnumerable IModel.GetEntityTypes()
/// 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? IMutableModel.FindEntityType(string name)
+ [DebuggerStepThrough]
+ IReadOnlyEntityType? IReadOnlyModel.FindEntityType(string name)
=> FindEntityType(name);
///
@@ -1029,8 +973,9 @@ IEnumerable IModel.GetEntityTypes()
/// 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 IMutableModel.AddEntityType(string name)
- => AddEntityType(name, ConfigurationSource.Explicit)!;
+ [DebuggerStepThrough]
+ IMutableEntityType? IMutableModel.FindEntityType(string name)
+ => FindEntityType(name);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1038,8 +983,9 @@ IMutableEntityType IMutableModel.AddEntityType(string name)
/// 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 IMutableModel.AddEntityType(Type type)
- => AddEntityType(type, ConfigurationSource.Explicit)!;
+ [DebuggerStepThrough]
+ IConventionEntityType? IConventionModel.FindEntityType(string name)
+ => FindEntityType(name);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1047,8 +993,9 @@ IMutableEntityType IMutableModel.AddEntityType(Type type)
/// 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 IMutableModel.AddEntityType(string name, Type type)
- => AddEntityType(name, type, ConfigurationSource.Explicit)!;
+ [DebuggerStepThrough]
+ IEntityType? IModel.FindEntityType(string name)
+ => FindEntityType(name);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1056,8 +1003,9 @@ IMutableEntityType IMutableModel.AddEntityType(string name, Type type)
/// 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? IMutableModel.RemoveEntityType(IMutableEntityType entityType)
- => RemoveEntityType((EntityType)entityType);
+ [DebuggerStepThrough]
+ IEntityType? IModel.FindEntityType(Type type)
+ => FindEntityType(type);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1065,7 +1013,8 @@ IMutableEntityType IMutableModel.AddEntityType(string name, Type type)
/// 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? IModel.FindEntityType(string name, string definingNavigationName, IEntityType definingEntityType)
+ [DebuggerStepThrough]
+ IReadOnlyEntityType? IReadOnlyModel.FindEntityType(string name, string definingNavigationName, IReadOnlyEntityType definingEntityType)
=> FindEntityType(name, definingNavigationName, (EntityType)definingEntityType);
///
@@ -1074,6 +1023,7 @@ IMutableEntityType IMutableModel.AddEntityType(string name, Type type)
/// 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]
IMutableEntityType? IMutableModel.FindEntityType(
string name,
string definingNavigationName,
@@ -1086,11 +1036,12 @@ IMutableEntityType IMutableModel.AddEntityType(string name, Type type)
/// 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 IMutableModel.AddEntityType(
+ [DebuggerStepThrough]
+ IConventionEntityType? IConventionModel.FindEntityType(
string name,
string definingNavigationName,
- IMutableEntityType definingEntityType)
- => AddEntityType(name, definingNavigationName, (EntityType)definingEntityType, ConfigurationSource.Explicit)!;
+ IConventionEntityType definingEntityType)
+ => FindEntityType(name, definingNavigationName, (EntityType)definingEntityType);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1098,11 +1049,12 @@ IMutableEntityType IMutableModel.AddEntityType(
/// 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 IMutableModel.AddEntityType(
- Type type,
+ [DebuggerStepThrough]
+ IEntityType? IModel.FindEntityType(
+ string name,
string definingNavigationName,
- IMutableEntityType definingEntityType)
- => AddEntityType(type, definingNavigationName, (EntityType)definingEntityType, ConfigurationSource.Explicit)!;
+ IEntityType definingEntityType)
+ => FindEntityType(name, definingNavigationName, (EntityType)definingEntityType);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1110,7 +1062,8 @@ IMutableEntityType IMutableModel.AddEntityType(
/// 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.
///
- IEnumerable IMutableModel.GetEntityTypes()
+ [DebuggerStepThrough]
+ IEnumerable IReadOnlyModel.GetEntityTypes()
=> GetEntityTypes();
///
@@ -1119,8 +1072,9 @@ IEnumerable IMutableModel.GetEntityTypes()
/// 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.
///
- string IMutableModel.AddIgnored(string name)
- => AddIgnored(name, ConfigurationSource.Explicit)!;
+ [DebuggerStepThrough]
+ IEnumerable IMutableModel.GetEntityTypes()
+ => GetEntityTypes();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1128,11 +1082,9 @@ string IMutableModel.AddIgnored(string name)
/// 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.
///
- IConventionModelBuilder IConventionModel.Builder
- {
- [DebuggerStepThrough]
- get => Builder;
- }
+ [DebuggerStepThrough]
+ IEnumerable IConventionModel.GetEntityTypes()
+ => GetEntityTypes();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1140,11 +1092,9 @@ IConventionModelBuilder IConventionModel.Builder
/// 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.
///
- IConventionAnnotatableBuilder IConventionAnnotatable.Builder
- {
- [DebuggerStepThrough]
- get => Builder;
- }
+ [DebuggerStepThrough]
+ IEnumerable IModel.GetEntityTypes()
+ => GetEntityTypes();
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1152,8 +1102,9 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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? IConventionModel.FindEntityType(string name)
- => FindEntityType(name);
+ [DebuggerStepThrough]
+ IEnumerable IModel.GetEntityTypes(Type type)
+ => GetEntityTypes(type);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1161,11 +1112,9 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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? IConventionModel.FindEntityType(
- string name,
- string definingNavigationName,
- IConventionEntityType definingEntityType)
- => FindEntityType(name, definingNavigationName, (EntityType)definingEntityType);
+ [DebuggerStepThrough]
+ IMutableEntityType IMutableModel.AddEntityType(string name)
+ => AddEntityType(name, ConfigurationSource.Explicit)!;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1173,6 +1122,7 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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]
IConventionEntityType? IConventionModel.AddEntityType(string name, bool fromDataAnnotation)
=> AddEntityType(name, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -1182,6 +1132,17 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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]
+ IMutableEntityType IMutableModel.AddEntityType(Type type)
+ => AddEntityType(type, 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.
+ ///
+ [DebuggerStepThrough]
IConventionEntityType? IConventionModel.AddEntityType(Type type, bool fromDataAnnotation)
=> AddEntityType(type, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -1191,9 +1152,33 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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]
+ IMutableEntityType IMutableModel.AddEntityType(string name, Type type)
+ => AddEntityType(name, type, 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.
+ ///
+ [DebuggerStepThrough]
IConventionEntityType? IConventionModel.AddEntityType(string name, Type type, bool fromDataAnnotation)
=> AddEntityType(name, type, 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.
+ ///
+ [DebuggerStepThrough]
+ IMutableEntityType IMutableModel.AddEntityType(
+ string name,
+ string definingNavigationName,
+ IMutableEntityType definingEntityType)
+ => AddEntityType(name, definingNavigationName, (EntityType)definingEntityType, 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
@@ -1201,6 +1186,7 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[Obsolete]
+ [DebuggerStepThrough]
IConventionEntityType? IConventionModel.AddEntityType(
string name,
string definingNavigationName,
@@ -1210,6 +1196,19 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
name, definingNavigationName, (EntityType)definingEntityType,
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.
+ ///
+ [DebuggerStepThrough]
+ IMutableEntityType IMutableModel.AddEntityType(
+ Type type,
+ string definingNavigationName,
+ IMutableEntityType definingEntityType)
+ => AddEntityType(type, definingNavigationName, (EntityType)definingEntityType, 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
@@ -1217,6 +1216,7 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
[Obsolete]
+ [DebuggerStepThrough]
IConventionEntityType? IConventionModel.AddEntityType(
Type type,
string definingNavigationName,
@@ -1232,6 +1232,17 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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]
+ IMutableEntityType? IMutableModel.RemoveEntityType(IMutableEntityType entityType)
+ => RemoveEntityType((EntityType)entityType);
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
IConventionEntityType? IConventionModel.RemoveEntityType(IConventionEntityType entityType)
=> RemoveEntityType((EntityType)entityType);
@@ -1241,8 +1252,9 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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.
///
- IEnumerable IConventionModel.GetEntityTypes()
- => GetEntityTypes();
+ [DebuggerStepThrough]
+ string IMutableModel.AddIgnored(string name)
+ => AddIgnored(name, ConfigurationSource.Explicit)!;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -1250,6 +1262,7 @@ IEnumerable IConventionModel.GetEntityTypes()
/// 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]
string? IConventionModel.AddIgnored(string name, bool fromDataAnnotation)
=> AddIgnored(name, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -1259,7 +1272,17 @@ IEnumerable IConventionModel.GetEntityTypes()
/// 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]
bool IConventionModel.IsShared(Type type)
=> IsShared(type);
+
+ ///
+ /// Set the runtime service dependencies.
+ ///
+ /// The runtime service dependencies.
+ /// if the runtime service dependencies were set; otherwise.
+ [DebuggerStepThrough]
+ bool IModel.SetModelDependencies(SingletonModelDependencies modelDependencies)
+ => Interlocked.CompareExchange(ref _modelDependencies, modelDependencies, null) == null;
}
}
diff --git a/src/EFCore/Metadata/Internal/ModelExtensions.cs b/src/EFCore/Metadata/Internal/ModelExtensions.cs
index 7f83658c3b9..8378617da59 100644
--- a/src/EFCore/Metadata/Internal/ModelExtensions.cs
+++ b/src/EFCore/Metadata/Internal/ModelExtensions.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 System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -42,7 +43,19 @@ public static IEnumerable GetRootEntityTypes([NotNull] this IModel
/// 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 Model AsModel([NotNull] this IModel model, [CallerMemberName] [NotNull] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(model, methodName);
+ public static string? FindSameTypeNameWithDifferentNamespace([NotNull] this IModel model, [NotNull] Type type)
+ => model.GetEntityTypes()
+ .Where(x => x.ClrType.DisplayName(false) == type.DisplayName(false))
+ .Select(x => x.ClrType.DisplayName())
+ .FirstOrDefault();
+
+ ///
+ /// 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 Model AsModel([NotNull] this IReadOnlyModel model, [CallerMemberName] [NotNull] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(model, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/Navigation.cs b/src/EFCore/Metadata/Internal/Navigation.cs
index ed7a65cb05d..d69aa927c24 100644
--- a/src/EFCore/Metadata/Internal/Navigation.cs
+++ b/src/EFCore/Metadata/Internal/Navigation.cs
@@ -21,7 +21,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 Navigation : PropertyBase, IMutableNavigation, IConventionNavigation
+ public class Navigation : PropertyBase, IMutableNavigation, IConventionNavigation, INavigation
{
private InternalNavigationBuilder? _builder;
@@ -104,7 +104,7 @@ public virtual void SetRemovedFromModel()
public virtual EntityType DeclaringEntityType
{
[DebuggerStepThrough]
- get => (EntityType)((INavigation)this).DeclaringEntityType;
+ get => (EntityType)((IReadOnlyNavigation)this).DeclaringEntityType;
}
///
@@ -116,7 +116,7 @@ public virtual EntityType DeclaringEntityType
public override TypeBase DeclaringType
{
[DebuggerStepThrough]
- get => (EntityType)((INavigation)this).DeclaringEntityType;
+ get => (EntityType)((IReadOnlyNavigation)this).DeclaringEntityType;
}
///
@@ -128,7 +128,7 @@ public override TypeBase DeclaringType
public virtual EntityType TargetEntityType
{
[DebuggerStepThrough]
- get => (EntityType)((INavigationBase)this).TargetEntityType;
+ get => (EntityType)((IReadOnlyNavigationBase)this).TargetEntityType;
}
///
@@ -253,7 +253,7 @@ public static bool IsCompatible(
public virtual Navigation? Inverse
{
[DebuggerStepThrough]
- get => (Navigation?)((INavigationBase)this).Inverse;
+ get => (Navigation?)((IReadOnlyNavigationBase)this).Inverse;
}
///
@@ -346,7 +346,7 @@ 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.
///
- IForeignKey INavigation.ForeignKey
+ IReadOnlyForeignKey IReadOnlyNavigation.ForeignKey
{
[DebuggerStepThrough] get => ForeignKey;
}
diff --git a/src/EFCore/Metadata/Internal/NavigationExtensions.cs b/src/EFCore/Metadata/Internal/NavigationExtensions.cs
index 3752d30a5e4..99681905a3e 100644
--- a/src/EFCore/Metadata/Internal/NavigationExtensions.cs
+++ b/src/EFCore/Metadata/Internal/NavigationExtensions.cs
@@ -23,7 +23,7 @@ public static class NavigationExtensions
/// 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 MemberIdentity CreateMemberIdentity([CanBeNull] this INavigation? navigation)
+ public static MemberIdentity CreateMemberIdentity([CanBeNull] this IReadOnlyNavigation? navigation)
=> navigation?.GetIdentifyingMemberInfo() == null
? MemberIdentity.Create(navigation?.Name)
: MemberIdentity.Create(navigation.GetIdentifyingMemberInfo());
@@ -34,8 +34,8 @@ public static MemberIdentity CreateMemberIdentity([CanBeNull] this INavigation?
/// 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 INavigation navigation, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(navigation, methodName);
+ 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
@@ -43,7 +43,7 @@ public static Navigation AsNavigation([NotNull] this INavigation navigation, [No
/// 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 ISkipNavigation navigation)
+ public static ICollectionLoader GetManyToManyLoader([NotNull] this IReadOnlySkipNavigation navigation)
=> ((SkipNavigation)navigation).ManyToManyLoader;
}
}
diff --git a/src/EFCore/Metadata/Internal/Property.cs b/src/EFCore/Metadata/Internal/Property.cs
index 8f68951bafb..6e08ff36648 100644
--- a/src/EFCore/Metadata/Internal/Property.cs
+++ b/src/EFCore/Metadata/Internal/Property.cs
@@ -27,7 +27,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 Property : PropertyBase, IMutableProperty, IConventionProperty
+ public class Property : PropertyBase, IMutableProperty, IConventionProperty, IProperty
{
private bool? _isConcurrencyToken;
private bool? _isNullable;
@@ -581,7 +581,7 @@ public virtual CoreTypeMapping? TypeMapping
/// 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 IKey? PrimaryKey { get; [param: CanBeNull] set; }
+ public virtual IReadOnlyKey? PrimaryKey { get; [param: CanBeNull] set; }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -729,7 +729,7 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
/// 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 IProperty.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyProperty.DeclaringEntityType
{
[DebuggerStepThrough] get => DeclaringEntityType;
}
@@ -762,6 +762,49 @@ IConventionEntityType IConventionProperty.DeclaringEntityType
/// 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 IProperty.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IProperty.GetContainingForeignKeys()
+ => GetContainingForeignKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IProperty.GetContainingIndexes()
+ => GetContainingIndexes();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
+ IEnumerable IProperty.GetContainingKeys()
+ => GetContainingKeys();
+
+ ///
+ /// 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.
+ ///
+ [DebuggerStepThrough]
bool? IConventionProperty.SetIsNullable(bool? nullable, bool fromDataAnnotation)
=> SetIsNullable(
nullable, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -772,6 +815,7 @@ IConventionEntityType IConventionProperty.DeclaringEntityType
/// 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]
ValueGenerated? IConventionProperty.SetValueGenerated(ValueGenerated? valueGenerated, bool fromDataAnnotation)
=> SetValueGenerated(
valueGenerated, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -782,6 +826,7 @@ IConventionEntityType IConventionProperty.DeclaringEntityType
/// 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]
bool? IConventionProperty.SetIsConcurrencyToken(bool? concurrencyToken, bool fromDataAnnotation)
=> SetIsConcurrencyToken(
concurrencyToken, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
diff --git a/src/EFCore/Metadata/Internal/PropertyBase.cs b/src/EFCore/Metadata/Internal/PropertyBase.cs
index a16c83af913..6058cbc13c9 100644
--- a/src/EFCore/Metadata/Internal/PropertyBase.cs
+++ b/src/EFCore/Metadata/Internal/PropertyBase.cs
@@ -25,7 +25,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 abstract class PropertyBase : ConventionAnnotatable, IMutablePropertyBase, IConventionPropertyBase
+ public abstract class PropertyBase : ConventionAnnotatable, IMutablePropertyBase, IConventionPropertyBase, IPropertyBase
{
private FieldInfo? _fieldInfo;
private ConfigurationSource _configurationSource;
@@ -70,7 +70,7 @@ protected PropertyBase(
///
/// Indicates whether the model is read-only.
///
- protected override bool IsReadOnly => DeclaringType.Model.IsModelReadOnly;
+ public override bool IsReadOnly => DeclaringType.Model.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -433,7 +433,7 @@ public virtual IComparer CurrentValueComparer
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static Expression CreateMemberAccess(
- [CanBeNull] IPropertyBase? property,
+ [CanBeNull] IReadOnlyPropertyBase? property,
[NotNull] Expression instanceExpression,
[NotNull] MemberInfo memberInfo)
{
@@ -463,7 +463,7 @@ public static Expression CreateMemberAccess(
/// 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.
///
- ITypeBase IPropertyBase.DeclaringType
+ IReadOnlyTypeBase IReadOnlyPropertyBase.DeclaringType
{
[DebuggerStepThrough] get => DeclaringType;
}
@@ -499,5 +499,15 @@ IConventionTypeBase IConventionPropertyBase.DeclaringType
[DebuggerStepThrough]
FieldInfo? IConventionPropertyBase.SetFieldInfo(FieldInfo? fieldInfo, bool fromDataAnnotation)
=> SetFieldInfo(fieldInfo, 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.
+ ///
+ [DebuggerStepThrough]
+ IClrPropertyGetter IPropertyBase.GetGetter()
+ => Getter;
}
}
diff --git a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
index 7e4867a04a1..9d4ab1db4b8 100644
--- a/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
+++ b/src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
@@ -83,7 +83,7 @@ public static PropertyAccessors GetPropertyAccessors([NotNull] this IPropertyBas
// Note: only use this to find the property/field that defines the property in the model. Use
// GetMemberInfo to get the property/field to use, which may be different.
public static MemberInfo? GetIdentifyingMemberInfo(
- [NotNull] this IPropertyBase propertyBase)
+ [NotNull] this IReadOnlyPropertyBase propertyBase)
=> propertyBase.PropertyInfo ?? (MemberInfo?)propertyBase.FieldInfo;
///
@@ -107,7 +107,7 @@ public static bool TryGetMemberInfo(
var setterProperty = propertyInfo?.FindSetterProperty();
var getterProperty = propertyInfo?.FindGetterProperty();
- var isCollectionNav = (propertyBase as INavigation)?.IsCollection == true;
+ var isCollectionNav = (propertyBase as IReadOnlyNavigation)?.IsCollection == true;
var hasField = fieldInfo != null;
var hasSetter = setterProperty != null;
var hasGetter = getterProperty != null;
@@ -359,8 +359,8 @@ private static string GetNoFieldErrorMessage(IPropertyBase propertyBase)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static PropertyBase AsPropertyBase(
- [NotNull] this IPropertyBase propertyBase,
+ [NotNull] this IReadOnlyPropertyBase propertyBase,
[NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(propertyBase, methodName);
+ => MetadataExtensions.AsConcreteMetadataType(propertyBase, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/PropertyExtensions.cs b/src/EFCore/Metadata/Internal/PropertyExtensions.cs
index d5f2ff28cf5..79fbb627d6c 100644
--- a/src/EFCore/Metadata/Internal/PropertyExtensions.cs
+++ b/src/EFCore/Metadata/Internal/PropertyExtensions.cs
@@ -2,7 +2,6 @@
// 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.Runtime.CompilerServices;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
@@ -37,24 +36,6 @@ public static bool ForAdd(this ValueGenerated valueGenerated)
public static bool ForUpdate(this ValueGenerated valueGenerated)
=> (valueGenerated & ValueGenerated.OnUpdate) != 0;
- ///
- /// 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 IEnumerable GetContainingEntityTypes([NotNull] this IProperty property)
- => property.DeclaringEntityType.GetDerivedTypesInclusive();
-
- ///
- /// 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 IEnumerable GetReferencingForeignKeys([NotNull] this IProperty property)
- => property.GetContainingKeys().SelectMany(k => k.GetReferencingForeignKeys());
-
///
/// 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
@@ -102,7 +83,7 @@ public static IEnumerable GetReferencingForeignKeys([NotNull] this
/// 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 bool RequiresValueGenerator([NotNull] this IProperty property)
+ public static bool RequiresValueGenerator([NotNull] this IReadOnlyProperty property)
=> (property.ValueGenerated.ForAdd()
&& property.IsKey()
&& (!property.IsForeignKey() || property.IsForeignKeyToSelf()))
@@ -114,7 +95,7 @@ public static bool RequiresValueGenerator([NotNull] this IProperty property)
/// 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 bool IsForeignKeyToSelf([NotNull] this IProperty property)
+ public static bool IsForeignKeyToSelf([NotNull] this IReadOnlyProperty property)
{
Check.DebugAssert(property.IsKey(), "Only call this method for properties known to be part of a key.");
@@ -160,7 +141,7 @@ public static bool MayBeStoreGenerated([NotNull] this IProperty property)
/// 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 bool RequiresOriginalValue([NotNull] this IProperty property)
+ public static bool RequiresOriginalValue([NotNull] this IReadOnlyProperty property)
=> property.DeclaringEntityType.GetChangeTrackingStrategy() != ChangeTrackingStrategy.ChangingAndChangedNotifications
|| property.IsConcurrencyToken
|| property.IsKey()
@@ -173,7 +154,7 @@ public static bool RequiresOriginalValue([NotNull] this IProperty property)
/// 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 Property AsProperty([NotNull] this IProperty property, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(property, methodName);
+ public static Property AsProperty([NotNull] this IReadOnlyProperty property, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(property, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/PropertyListComparer.cs b/src/EFCore/Metadata/Internal/PropertyListComparer.cs
index c0e92cd33a9..8c9915b16c7 100644
--- a/src/EFCore/Metadata/Internal/PropertyListComparer.cs
+++ b/src/EFCore/Metadata/Internal/PropertyListComparer.cs
@@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
// Sealed for perf
- public sealed class PropertyListComparer : IComparer>, IEqualityComparer>
+ public sealed class PropertyListComparer : IComparer>, IEqualityComparer>
{
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -35,7 +35,7 @@ private PropertyListComparer()
/// 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 int Compare(IReadOnlyList? x, IReadOnlyList? y)
+ public int Compare(IReadOnlyList? x, IReadOnlyList? y)
{
if (ReferenceEquals(x, y))
{
@@ -76,7 +76,7 @@ public int Compare(IReadOnlyList? x, IReadOnlyList? y)
/// 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 bool Equals(IReadOnlyList? x, IReadOnlyList? y)
+ public bool Equals(IReadOnlyList? x, IReadOnlyList? y)
=> Compare(x, y) == 0;
///
@@ -85,7 +85,7 @@ public bool Equals(IReadOnlyList? x, IReadOnlyList? y)
/// 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 int GetHashCode(IReadOnlyList obj)
+ public int GetHashCode(IReadOnlyList obj)
{
var hash = new HashCode();
for (var i = 0; i < obj.Count; i++)
diff --git a/src/EFCore/Metadata/Internal/ServiceProperty.cs b/src/EFCore/Metadata/Internal/ServiceProperty.cs
index 2f95c13a4ed..5bf94f53f91 100644
--- a/src/EFCore/Metadata/Internal/ServiceProperty.cs
+++ b/src/EFCore/Metadata/Internal/ServiceProperty.cs
@@ -20,7 +20,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 ServiceProperty : PropertyBase, IMutableServiceProperty, IConventionServiceProperty
+ public class ServiceProperty : PropertyBase, IMutableServiceProperty, IConventionServiceProperty, IServiceProperty
{
private ServiceParameterBinding? _parameterBinding;
private InternalServicePropertyBuilder? _builder;
@@ -167,7 +167,7 @@ private void UpdateParameterBindingConfigurationSource(ConfigurationSource confi
/// 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 IServiceProperty.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyServiceProperty.DeclaringEntityType
{
[DebuggerStepThrough] get => DeclaringEntityType;
}
@@ -202,7 +202,8 @@ IConventionServicePropertyBuilder IConventionServiceProperty.Builder
///
IConventionAnnotatableBuilder IConventionAnnotatable.Builder
{
- [DebuggerStepThrough] get => Builder;
+ [DebuggerStepThrough]
+ get => Builder;
}
///
@@ -213,7 +214,14 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
///
IConventionEntityType IConventionServiceProperty.DeclaringEntityType
{
- [DebuggerStepThrough] get => DeclaringEntityType;
+ [DebuggerStepThrough]
+ get => DeclaringEntityType;
+ }
+
+ IEntityType IServiceProperty.DeclaringEntityType
+ {
+ [DebuggerStepThrough]
+ get => DeclaringEntityType;
}
///
diff --git a/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs b/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs
index f0d2b4889a5..214a77ea521 100644
--- a/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs
+++ b/src/EFCore/Metadata/Internal/ServicePropertyExtensions.cs
@@ -32,8 +32,8 @@ public static class ServicePropertyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static ServiceProperty AsServiceProperty(
- [NotNull] this IServiceProperty serviceProperty,
+ [NotNull] this IReadOnlyServiceProperty serviceProperty,
[NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(serviceProperty, methodName);
+ => MetadataExtensions.AsConcreteMetadataType(serviceProperty, methodName);
}
}
diff --git a/src/EFCore/Metadata/Internal/SkipNavigation.cs b/src/EFCore/Metadata/Internal/SkipNavigation.cs
index d30e17b325f..681b5fa7c30 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
+ public class SkipNavigation : PropertyBase, IMutableSkipNavigation, IConventionSkipNavigation, ISkipNavigation
{
private ConfigurationSource? _foreignKeyConfigurationSource;
private ConfigurationSource? _inverseConfigurationSource;
@@ -412,21 +412,21 @@ IConventionAnnotatableBuilder IConventionAnnotatable.Builder
}
///
- IEntityType INavigationBase.DeclaringEntityType
+ IReadOnlyEntityType IReadOnlyNavigationBase.DeclaringEntityType
{
[DebuggerStepThrough]
get => DeclaringEntityType;
}
///
- IEntityType INavigationBase.TargetEntityType
+ IReadOnlyEntityType IReadOnlyNavigationBase.TargetEntityType
{
[DebuggerStepThrough]
get => TargetEntityType;
}
///
- IForeignKey ISkipNavigation.ForeignKey
+ IReadOnlyForeignKey IReadOnlySkipNavigation.ForeignKey
{
// ModelValidator makes sure ForeignKey isn't null, so we expose it as non-nullable.
[DebuggerStepThrough]
@@ -445,7 +445,7 @@ void IMutableSkipNavigation.SetForeignKey(IMutableForeignKey? foreignKey)
(ForeignKey?)foreignKey, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
///
- ISkipNavigation ISkipNavigation.Inverse
+ IReadOnlySkipNavigation IReadOnlySkipNavigation.Inverse
{
// ModelValidator makes sure ForeignKey isn't null, so we expose it as non-nullable.
[DebuggerStepThrough]
diff --git a/src/EFCore/Metadata/Internal/SkipNavigationExtensions.cs b/src/EFCore/Metadata/Internal/SkipNavigationExtensions.cs
index 6095477522c..600b66716b8 100644
--- a/src/EFCore/Metadata/Internal/SkipNavigationExtensions.cs
+++ b/src/EFCore/Metadata/Internal/SkipNavigationExtensions.cs
@@ -21,7 +21,7 @@ public static class SkipNavigationExtensions
/// 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 MemberIdentity CreateMemberIdentity([CanBeNull] this ISkipNavigation? navigation)
+ public static MemberIdentity CreateMemberIdentity([CanBeNull] this IReadOnlySkipNavigation? navigation)
=> navigation?.GetIdentifyingMemberInfo() == null
? MemberIdentity.Create(navigation?.Name)
: MemberIdentity.Create(navigation.GetIdentifyingMemberInfo());
diff --git a/src/EFCore/Metadata/Internal/TypeBase.cs b/src/EFCore/Metadata/Internal/TypeBase.cs
index fb7f731e3ad..14a90ad0f09 100644
--- a/src/EFCore/Metadata/Internal/TypeBase.cs
+++ b/src/EFCore/Metadata/Internal/TypeBase.cs
@@ -10,7 +10,6 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
-using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -22,7 +21,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 abstract class TypeBase : ConventionAnnotatable, IMutableTypeBase, IConventionTypeBase
+ public abstract class TypeBase : ConventionAnnotatable, IMutableTypeBase, IConventionTypeBase, ITypeBase
{
private ConfigurationSource _configurationSource;
@@ -94,7 +93,7 @@ protected TypeBase([NotNull] string name, [NotNull] Type type, [NotNull] Model m
/// 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.
///
- protected override bool IsReadOnly => Model.IsModelReadOnly;
+ public override bool IsReadOnly => Model.IsReadOnly;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -328,7 +327,7 @@ public virtual bool IsIgnored(string name)
/// 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.
///
- IModel ITypeBase.Model
+ IReadOnlyModel IReadOnlyTypeBase.Model
{
[DebuggerStepThrough] get => Model;
}
@@ -361,7 +360,19 @@ IConventionModel IConventionTypeBase.Model
/// 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.
///
- Type ITypeBase.ClrType
+ IModel ITypeBase.Model
+ {
+ [DebuggerStepThrough]
+ get => Model;
+ }
+
+ ///
+ /// 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.
+ ///
+ Type IReadOnlyTypeBase.ClrType
{
[DebuggerStepThrough] get => ClrType;
}
diff --git a/src/EFCore/Metadata/Internal/TypeBaseExtensions.cs b/src/EFCore/Metadata/Internal/TypeBaseExtensions.cs
index 0ea1ed8b815..d488645b939 100644
--- a/src/EFCore/Metadata/Internal/TypeBaseExtensions.cs
+++ b/src/EFCore/Metadata/Internal/TypeBaseExtensions.cs
@@ -24,7 +24,7 @@ public static class TypeBaseExtensions
/// 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 IReadOnlyDictionary GetRuntimeProperties([NotNull] this ITypeBase type)
+ public static IReadOnlyDictionary GetRuntimeProperties([NotNull] this IReadOnlyTypeBase type)
=> ((TypeBase)type).GetRuntimeProperties();
///
@@ -33,7 +33,7 @@ public static IReadOnlyDictionary GetRuntimeProperties([No
/// 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 IReadOnlyDictionary GetRuntimeFields([NotNull] this ITypeBase type)
+ public static IReadOnlyDictionary GetRuntimeFields([NotNull] this IReadOnlyTypeBase type)
=> ((TypeBase)type).GetRuntimeFields();
///
@@ -42,7 +42,7 @@ public static IReadOnlyDictionary GetRuntimeFields([NotNull]
/// 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 PropertyInfo? FindIndexerPropertyInfo([NotNull] this ITypeBase type)
+ public static PropertyInfo? FindIndexerPropertyInfo([NotNull] this IReadOnlyTypeBase type)
=> ((TypeBase)type).FindIndexerPropertyInfo();
///
@@ -51,7 +51,7 @@ public static IReadOnlyDictionary GetRuntimeFields([NotNull]
/// 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 TypeBase AsTypeBase([NotNull] this ITypeBase entityType, [NotNull] [CallerMemberName] string methodName = "")
- => MetadataExtensions.AsConcreteMetadataType(entityType, methodName);
+ public static TypeBase AsTypeBase([NotNull] this IReadOnlyTypeBase entityType, [NotNull] [CallerMemberName] string methodName = "")
+ => MetadataExtensions.AsConcreteMetadataType(entityType, methodName);
}
}
diff --git a/src/EFCore/Metadata/KeyComparer.cs b/src/EFCore/Metadata/KeyComparer.cs
index 64c19618055..95a7e07ffcb 100644
--- a/src/EFCore/Metadata/KeyComparer.cs
+++ b/src/EFCore/Metadata/KeyComparer.cs
@@ -12,14 +12,14 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
///
/// An implementation of and to compare
- /// instances.
+ /// instances.
///
///
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
///
///
- public sealed class KeyComparer : IEqualityComparer, IComparer
+ public sealed class KeyComparer : IEqualityComparer, IComparer
{
private KeyComparer()
{
@@ -36,7 +36,7 @@ private KeyComparer()
/// The first object to compare.
/// The second object to compare.
/// A negative number if 'x' is less than 'y'; a positive number if 'x' is greater than 'y'; zero otherwise.
- public int Compare(IKey? x, IKey? y)
+ public int Compare(IReadOnlyKey? x, IReadOnlyKey? y)
{
var result = PropertyListComparer.Instance.Compare(x?.Properties, y?.Properties);
return result != 0 ? result : EntityTypeFullNameComparer.Instance.Compare(x?.DeclaringEntityType, y?.DeclaringEntityType);
@@ -48,7 +48,7 @@ public int Compare(IKey? x, IKey? y)
/// The first object to compare.
/// The second object to compare.
/// if the specified objects are equal; otherwise, .
- public bool Equals(IKey? x, IKey? y)
+ public bool Equals(IReadOnlyKey? x, IReadOnlyKey? y)
=> Compare(x, y) == 0;
///
@@ -56,7 +56,7 @@ public bool Equals(IKey? x, IKey? y)
///
/// The for which a hash code is to be returned.
/// A hash code for the specified object.
- public int GetHashCode(IKey obj)
+ public int GetHashCode(IReadOnlyKey obj)
{
var hashCode = new HashCode();
hashCode.Add(obj.Properties, PropertyListComparer.Instance);
diff --git a/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs b/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs
index b30165b0213..4f4034c5651 100644
--- a/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs
+++ b/src/EFCore/Metadata/LazyLoaderParameterBindingFactory.cs
@@ -83,7 +83,7 @@ public override ParameterBinding Bind(
}
while (baseType != null);
- return Bind(entityType, parameterType);
+ return Bind((IEntityType)entityType, parameterType);
}
///
@@ -110,7 +110,7 @@ public override ParameterBinding Bind(
}
while (baseType != null);
- return Bind(entityType, parameterType);
+ return Bind((IEntityType)entityType, parameterType);
}
private static ParameterBinding Bind(IEntityType entityType, Type parameterType)
diff --git a/src/EFCore/Metadata/ServiceParameterBindingFactory.cs b/src/EFCore/Metadata/ServiceParameterBindingFactory.cs
index 4decec7aa4e..f3957eb7dc5 100644
--- a/src/EFCore/Metadata/ServiceParameterBindingFactory.cs
+++ b/src/EFCore/Metadata/ServiceParameterBindingFactory.cs
@@ -64,7 +64,7 @@ public virtual ParameterBinding Bind(IMutableEntityType entityType, Type paramet
return new DependencyInjectionParameterBinding(
_serviceType,
_serviceType,
- entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == _serviceType));
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == _serviceType));
}
///
@@ -86,7 +86,7 @@ public virtual ParameterBinding Bind(
return new DependencyInjectionParameterBinding(
_serviceType,
_serviceType,
- entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == _serviceType));
+ (IPropertyBase?)entityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == _serviceType));
}
}
}
diff --git a/src/EFCore/ModelBuilder.cs b/src/EFCore/ModelBuilder.cs
index 5261de4a36a..8a2c9aed00f 100644
--- a/src/EFCore/ModelBuilder.cs
+++ b/src/EFCore/ModelBuilder.cs
@@ -544,7 +544,7 @@ public virtual ModelBuilder UsePropertyAccessMode(PropertyAccessMode propertyAcc
/// processing happens automatically when using ; this method allows it to be run
/// explicitly in cases where the automatic execution is not possible.
///
- /// The finalized .
+ /// The finalized model.
public virtual IModel FinalizeModel()
=> Builder.Metadata.FinalizeModel();
diff --git a/src/EFCore/Update/Internal/UpdateAdapter.cs b/src/EFCore/Update/Internal/UpdateAdapter.cs
index 963e5c90907..8a53b510f92 100644
--- a/src/EFCore/Update/Internal/UpdateAdapter.cs
+++ b/src/EFCore/Update/Internal/UpdateAdapter.cs
@@ -166,7 +166,6 @@ public virtual IUpdateEntry CreateEntry(
/// 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 IModel Model
- => _stateManager.Model;
+ public virtual IModel Model => _stateManager.Model;
}
}
diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs
index 540b2bca304..9fa5f21ffc2 100644
--- a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs
@@ -37,14 +37,30 @@ public class CosmosApiConsistencyFixture : ApiConsistencyFixtureBase
};
public override
- List<(Type Type, Type ReadonlyExtensions, Type MutableExtensions, Type ConventionExtensions, Type
- ConventionBuilderExtensions)> MetadataExtensionTypes { get; }
+ List<(Type Type,
+ Type ReadonlyExtensions,
+ Type MutableExtensions,
+ Type ConventionExtensions,
+ Type ConventionBuilderExtensions,
+ Type RuntimeExtensions)> MetadataExtensionTypes { get; }
= new()
{
- (typeof(IModel), typeof(CosmosModelExtensions), typeof(CosmosModelExtensions), typeof(CosmosModelExtensions),
- typeof(CosmosModelBuilderExtensions)),
- (typeof(IProperty), typeof(CosmosPropertyExtensions), typeof(CosmosPropertyExtensions),
- typeof(CosmosPropertyExtensions), typeof(CosmosPropertyBuilderExtensions))
+ (
+ typeof(IReadOnlyModel),
+ typeof(CosmosModelExtensions),
+ typeof(CosmosModelExtensions),
+ typeof(CosmosModelExtensions),
+ typeof(CosmosModelBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyProperty),
+ typeof(CosmosPropertyExtensions),
+ typeof(CosmosPropertyExtensions),
+ typeof(CosmosPropertyExtensions),
+ typeof(CosmosPropertyBuilderExtensions),
+ null
+ )
};
}
}
diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
index 9ace098eac6..9d5fad851e6 100644
--- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs
@@ -333,18 +333,46 @@ public bool HasSharedClrType
public bool IsPropertyBag
=> throw new NotImplementedException();
+ IReadOnlyEntityType IReadOnlyEntityType.BaseType
+ => throw new NotImplementedException();
+
+ IReadOnlyModel IReadOnlyTypeBase.Model
+ => throw new NotImplementedException();
+
+ public IEnumerable FindDeclaredForeignKeys(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
+ public INavigation FindDeclaredNavigation(string name)
+ => throw new NotImplementedException();
+
+ public IProperty FindDeclaredProperty(string name)
+ => throw new NotImplementedException();
+
public IForeignKey FindForeignKey(IReadOnlyList properties, IKey principalKey, IEntityType principalEntityType)
=> throw new NotImplementedException();
+ public IForeignKey FindForeignKey(
+ IReadOnlyList properties, IReadOnlyKey principalKey, IReadOnlyEntityType principalEntityType)
+ => throw new NotImplementedException();
+
+ public IEnumerable FindForeignKeys(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
public IIndex FindIndex(IReadOnlyList properties)
=> throw new NotImplementedException();
public IIndex FindIndex(string name)
=> throw new NotImplementedException();
+ public IIndex FindIndex(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
public IKey FindKey(IReadOnlyList properties)
=> throw new NotImplementedException();
+ public IKey FindKey(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
public IKey FindPrimaryKey()
=> throw new NotImplementedException();
@@ -357,6 +385,39 @@ public IServiceProperty FindServiceProperty(string name)
public ISkipNavigation FindSkipNavigation(string name)
=> throw new NotImplementedException();
+ public IEnumerable GetDeclaredForeignKeys()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredIndexes()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredKeys()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredNavigations()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredProperties()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredReferencingForeignKeys()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDeclaredServiceProperties()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDerivedForeignKeys()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDerivedIndexes()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetDirectlyDerivedTypes()
+ => throw new NotImplementedException();
+
+ public IEnumerable GetForeignKeyProperties()
+ => throw new NotImplementedException();
+
public IEnumerable GetForeignKeys()
=> throw new NotImplementedException();
@@ -369,11 +430,60 @@ public IEnumerable GetKeys()
public IEnumerable GetProperties()
=> throw new NotImplementedException();
+ public IEnumerable GetReferencingForeignKeys()
+ => throw new NotImplementedException();
+
public IEnumerable GetServiceProperties()
=> throw new NotImplementedException();
public IEnumerable GetSkipNavigations()
=> throw new NotImplementedException();
+
+ public IEnumerable GetValueGeneratingProperties()
+ => throw new NotImplementedException();
+
+ IReadOnlyForeignKey IReadOnlyEntityType.FindForeignKey(
+ IReadOnlyList properties, IReadOnlyKey principalKey, IReadOnlyEntityType principalEntityType)
+ => throw new NotImplementedException();
+
+ IReadOnlyIndex IReadOnlyEntityType.FindIndex(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
+ IReadOnlyIndex IReadOnlyEntityType.FindIndex(string name)
+ => throw new NotImplementedException();
+
+ IReadOnlyKey IReadOnlyEntityType.FindKey(IReadOnlyList properties)
+ => throw new NotImplementedException();
+
+ IReadOnlyKey IReadOnlyEntityType.FindPrimaryKey()
+ => throw new NotImplementedException();
+
+ IReadOnlyProperty IReadOnlyEntityType.FindProperty(string name)
+ => throw new NotImplementedException();
+
+ IReadOnlyServiceProperty IReadOnlyEntityType.FindServiceProperty(string name)
+ => throw new NotImplementedException();
+
+ IReadOnlySkipNavigation IReadOnlyEntityType.FindSkipNavigation(string name)
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetForeignKeys()
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetIndexes()
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetKeys()
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetProperties()
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetServiceProperties()
+ => throw new NotImplementedException();
+
+ IEnumerable IReadOnlyEntityType.GetSkipNavigations()
+ => throw new NotImplementedException();
}
}
}
diff --git a/test/EFCore.Cosmos.Tests/Metadata/Conventions/CosmosConventionSetBuilderTests.cs b/test/EFCore.Cosmos.Tests/Metadata/Conventions/CosmosConventionSetBuilderTests.cs
index 5a5b420afb1..0bf01572741 100644
--- a/test/EFCore.Cosmos.Tests/Metadata/Conventions/CosmosConventionSetBuilderTests.cs
+++ b/test/EFCore.Cosmos.Tests/Metadata/Conventions/CosmosConventionSetBuilderTests.cs
@@ -9,12 +9,12 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
public class CosmosConventionSetBuilderTests : ConventionSetBuilderTests
{
- public override IModel Can_build_a_model_with_default_conventions_without_DI()
+ public override IReadOnlyModel Can_build_a_model_with_default_conventions_without_DI()
{
return null;
}
- public override IModel Can_build_a_model_with_default_conventions_without_DI_new()
+ public override IReadOnlyModel Can_build_a_model_with_default_conventions_without_DI_new()
{
var model = base.Can_build_a_model_with_default_conventions_without_DI_new();
diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs
index 46838bd9e7f..301bb31e568 100644
--- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs
+++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs
@@ -389,13 +389,13 @@ public void Snapshot_with_enum_discriminator_uses_converted_values()
eb.Property("EnumDiscriminator").HasConversion();
});
- modelBuilder.FinalizeModel();
+ var finalizedModel = modelBuilder.FinalizeModel();
var modelSnapshotCode = generator.GenerateSnapshot(
"MyNamespace",
typeof(MyContext),
"MySnapshot",
- modelBuilder.Model);
+ finalizedModel);
var snapshotModel = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot").Model;
@@ -427,7 +427,7 @@ private static void AssertConverter(ValueConverter valueConverter, string expect
var sb = new IndentedStringBuilder();
- generator.TestGeneratePropertyAnnotations(property, sb);
+ generator.TestGeneratePropertyAnnotations((IProperty)property, sb);
Assert.Equal(expected + _nl + ".HasMaxLength(1000)", sb.ToString());
}
@@ -519,12 +519,14 @@ protected override void Down(MigrationBuilder migrationBuilder)
eb.HasKey("Id");
});
+ var finalizedModel = modelBuilder.FinalizeModel();
+
var migrationMetadataCode = generator.GenerateMetadata(
"MyNamespace",
typeof(MyContext),
"MyMigration",
"20150511161616_MyMigration",
- modelBuilder.Model);
+ finalizedModel);
Assert.Equal(
@"//
using System.Text.RegularExpressions;
@@ -649,13 +651,13 @@ public void Snapshots_compile()
entityType.SetPrimaryKey(property2);
- modelBuilder.FinalizeModel();
+ var finalizedModel = modelBuilder.FinalizeModel();
var modelSnapshotCode = generator.GenerateSnapshot(
"MyNamespace",
typeof(MyContext),
"MySnapshot",
- model);
+ finalizedModel);
Assert.Equal(
@"//
using System;
@@ -765,13 +767,13 @@ public void Snapshot_with_default_values_are_round_tripped()
eb.HasKey(e => e.Boolean);
});
- modelBuilder.FinalizeModel();
+ var finalizedModel = modelBuilder.FinalizeModel();
var modelSnapshotCode = generator.GenerateSnapshot(
"MyNamespace",
typeof(MyContext),
"MySnapshot",
- modelBuilder.Model);
+ finalizedModel);
var snapshot = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot");
var entityType = snapshot.Model.GetEntityTypes().Single();
diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
index 6e99aa8c2a2..bcf68177e72 100644
--- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
+++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
@@ -689,7 +689,7 @@ public virtual void ProductVersion_is_stored_in_snapshot()
{
var modelBuilder = CreateConventionalModelBuilder();
var generator = CreateMigrationsGenerator();
- var code = generator.GenerateSnapshot("RootNamespace", typeof(DbContext), "Snapshot", modelBuilder.Model);
+ var code = generator.GenerateSnapshot("RootNamespace", typeof(DbContext), "Snapshot", (IModel)modelBuilder.Model);
Assert.Contains(@".HasAnnotation(""ProductVersion"",", code);
var modelFromSnapshot = BuildModelFromSnapshotSource(code);
@@ -1509,7 +1509,7 @@ public virtual void Can_override_table_name_for_many_to_many_join_table_stored_i
[ConditionalFact]
public virtual void TableName_preserved_when_generic()
{
- IModel originalModel = null;
+ IReadOnlyModel originalModel = null;
Test(
builder =>
@@ -1621,7 +1621,7 @@ public virtual void Shared_columns_are_stored_in_the_snapshot()
[ConditionalFact]
public virtual void PrimaryKey_name_preserved_when_generic()
{
- IModel originalModel = null;
+ IReadOnlyModel originalModel = null;
Test(
builder =>
@@ -1659,7 +1659,7 @@ public virtual void PrimaryKey_name_preserved_when_generic()
[ConditionalFact]
public virtual void AlternateKey_name_preserved_when_generic()
{
- IModel originalModel = null;
+ IReadOnlyModel originalModel = null;
Test(
builder =>
@@ -4265,7 +4265,7 @@ public virtual void ForeignKey_deleteBehavior_is_stored_in_snapshot_for_one_to_o
[ConditionalFact]
public virtual void ForeignKey_name_preserved_when_generic()
{
- IModel originalModel = null;
+ IReadOnlyModel originalModel = null;
Test(
builder =>
diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpModelGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpModelGeneratorTest.cs
index 77fa2699b2d..7fcbfa1b67b 100644
--- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpModelGeneratorTest.cs
+++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpModelGeneratorTest.cs
@@ -30,11 +30,8 @@ public void WriteCode_works()
var modelBuilder = RelationalTestHelpers.Instance.CreateConventionBuilder();
modelBuilder.Entity("TestEntity").Property("Id").HasAnnotation(ScaffoldingAnnotationNames.ColumnOrdinal, 0);
- var model = (Model)modelBuilder.Model;
- var finalizedModel = model.ConventionDispatcher.OnModelFinalizing(model.Builder)?.Metadata;
-
var result = generator.GenerateModel(
- finalizedModel,
+ modelBuilder.FinalizeModel(),
new ModelCodeGenerationOptions
{
ModelNamespace = "TestNamespace",
diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs
index 31c30ae5966..c78f7503f45 100644
--- a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs
+++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs
@@ -25,7 +25,6 @@ protected void Test(
var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder();
modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion);
buildModel(modelBuilder);
- var _ = modelBuilder.Model.GetEntityTypeErrors();
var model = modelBuilder.FinalizeModel();
diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingMetadataExtensionsTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingMetadataExtensionsTest.cs
index 70cdd81341c..ff534684213 100644
--- a/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingMetadataExtensionsTest.cs
+++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ScaffoldingMetadataExtensionsTest.cs
@@ -16,14 +16,16 @@ public void It_sets_gets_entity_type_errors()
{
IMutableModel model = new Model();
- model.GetEntityTypeErrors().Add("ET", "FAIL!");
+ Assert.Empty(model.GetEntityTypeErrors().Values);
+
+ model.GetOrCreateEntityTypeErrors().Add("ET", "FAIL!");
Assert.Equal("FAIL!", model.GetEntityTypeErrors()["ET"]);
model.SetEntityTypeErrors(new Dictionary());
Assert.Empty(model.GetEntityTypeErrors().Values);
- model.GetEntityTypeErrors()["ET"] = "FAIL 2!";
- model.GetEntityTypeErrors().Clear();
+ model.GetOrCreateEntityTypeErrors()["ET"] = "FAIL 2!";
+ model.GetOrCreateEntityTypeErrors().Clear();
Assert.Empty(model.GetEntityTypeErrors().Values);
}
diff --git a/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs b/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs
index a44d36e60c6..65cb012a96c 100644
--- a/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs
+++ b/test/EFCore.InMemory.FunctionalTests/ShadowStateUpdateTest.cs
@@ -15,13 +15,14 @@ public class ShadowStateUpdateTest : IClassFixture
[ConditionalFact]
public async Task Can_add_update_delete_end_to_end_using_partial_shadow_state()
{
- IMutableModel model = InMemoryTestHelpers.Instance.CreateConventionBuilder().Model;
+ var modelBuilder = InMemoryTestHelpers.Instance.CreateConventionBuilder();
+ var entityTypeBuilder = modelBuilder.Entity();
+ entityTypeBuilder.Property("Name");
- var customerType = model.AddEntityType(typeof(Customer));
- customerType.AddProperty("Name", typeof(string));
+ var customerType = (IEntityType)entityTypeBuilder.Metadata;
var optionsBuilder = new DbContextOptionsBuilder()
- .UseModel(model.FinalizeModel())
+ .UseModel(modelBuilder.FinalizeModel())
.UseInMemoryDatabase(nameof(ShadowStateUpdateTest))
.UseInternalServiceProvider(_fixture.ServiceProvider);
diff --git a/test/EFCore.InMemory.Tests/InMemoryDatabaseCreatorTest.cs b/test/EFCore.InMemory.Tests/InMemoryDatabaseCreatorTest.cs
index cf7ea9199b2..bd905a2a743 100644
--- a/test/EFCore.InMemory.Tests/InMemoryDatabaseCreatorTest.cs
+++ b/test/EFCore.InMemory.Tests/InMemoryDatabaseCreatorTest.cs
@@ -140,7 +140,7 @@ private static IModel CreateModel()
b.HasData(new Test { Id = 1 });
});
- return modelBuilder.Model;
+ return modelBuilder.FinalizeModel();
}
private class Test
diff --git a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs
index 0809f5a3242..647c30a7f0c 100644
--- a/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs
+++ b/test/EFCore.Relational.Specification.Tests/TestUtilities/RelationalDatabaseCleaner.cs
@@ -6,6 +6,7 @@
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Scaffolding;
@@ -96,7 +97,7 @@ public virtual void Clean(DatabaseFacade facade)
if (operations.Count > 0)
{
- var commands = sqlGenerator.Generate(operations);
+ var commands = sqlGenerator.Generate(operations, null);
executor.ExecuteNonQuery(commands, connection);
}
diff --git a/test/EFCore.Relational.Specification.Tests/Update/UpdateSqlGeneratorTestBase.cs b/test/EFCore.Relational.Specification.Tests/Update/UpdateSqlGeneratorTestBase.cs
index b6361a1b32b..b42b552b867 100644
--- a/test/EFCore.Relational.Specification.Tests/Update/UpdateSqlGeneratorTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Update/UpdateSqlGeneratorTestBase.cs
@@ -667,11 +667,12 @@ protected virtual string GetIdentityWhereCondition(string columnName)
protected ModificationCommand CreateInsertCommand(bool identityKey = true, bool isComputed = true, bool defaultsOnly = false)
{
- var duckType = GetDuckType();
- var stateManager = TestHelpers.CreateContextServices(duckType.Model.FinalizeModel()).GetRequiredService();
+ var model = GetDuckType().Model.FinalizeModel();
+ var stateManager = TestHelpers.CreateContextServices(model).GetRequiredService();
var entry = stateManager.GetOrCreateEntry(new Duck());
var generator = new ParameterNameGenerator();
+ var duckType = model.FindEntityType(typeof(Duck));
var idProperty = duckType.FindProperty(nameof(Duck.Id));
var nameProperty = duckType.FindProperty(nameof(Duck.Name));
var quacksProperty = duckType.FindProperty(nameof(Duck.Quacks));
@@ -706,11 +707,12 @@ protected ModificationCommand CreateInsertCommand(bool identityKey = true, bool
protected ModificationCommand CreateUpdateCommand(bool isComputed = true, bool concurrencyToken = true)
{
- var duckType = GetDuckType();
- var stateManager = TestHelpers.CreateContextServices(duckType.Model.FinalizeModel()).GetRequiredService();
+ var model = GetDuckType().Model.FinalizeModel();
+ var stateManager = TestHelpers.CreateContextServices(model).GetRequiredService();
var entry = stateManager.GetOrCreateEntry(new Duck());
var generator = new ParameterNameGenerator();
+ var duckType = model.FindEntityType(typeof(Duck));
var idProperty = duckType.FindProperty(nameof(Duck.Id));
var nameProperty = duckType.FindProperty(nameof(Duck.Name));
var quacksProperty = duckType.FindProperty(nameof(Duck.Quacks));
@@ -740,11 +742,12 @@ protected ModificationCommand CreateUpdateCommand(bool isComputed = true, bool c
protected ModificationCommand CreateDeleteCommand(bool concurrencyToken = true)
{
- var duckType = GetDuckType();
- var stateManager = TestHelpers.CreateContextServices(duckType.Model.FinalizeModel()).GetRequiredService();
+ var model = GetDuckType().Model.FinalizeModel();
+ var stateManager = TestHelpers.CreateContextServices(model).GetRequiredService();
var entry = stateManager.GetOrCreateEntry(new Duck());
var generator = new ParameterNameGenerator();
+ var duckType = model.FindEntityType(typeof(Duck));
var idProperty = duckType.FindProperty(nameof(Duck.Id));
var concurrencyProperty = duckType.FindProperty(nameof(Duck.ConcurrencyToken));
var columnModifications = new[]
diff --git a/test/EFCore.Relational.Tests/Design/AnnotationCodeGeneratorTest.cs b/test/EFCore.Relational.Tests/Design/AnnotationCodeGeneratorTest.cs
index 3dd18625a57..5829436d7de 100644
--- a/test/EFCore.Relational.Tests/Design/AnnotationCodeGeneratorTest.cs
+++ b/test/EFCore.Relational.Tests/Design/AnnotationCodeGeneratorTest.cs
@@ -19,7 +19,7 @@ public void IsTableExcludedFromMigrations_false_is_handled_by_convention()
var entityType = modelBuilder.Model.GetEntityTypes().Single();
var annotations = entityType.GetAnnotations().ToDictionary(a => a.Name, a => a);
- CreateGenerator().RemoveAnnotationsHandledByConventions(entityType, annotations);
+ CreateGenerator().RemoveAnnotationsHandledByConventions((IEntityType)entityType, annotations);
Assert.DoesNotContain(RelationalAnnotationNames.IsTableExcludedFromMigrations, annotations.Keys);
}
diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs
index d5b82803a50..ca3941c24b0 100644
--- a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs
+++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs
@@ -949,8 +949,8 @@ public virtual void Passes_for_incompatible_foreignKeys_within_hierarchy_when_on
public virtual void Passes_for_compatible_duplicate_foreignKey_names_within_hierarchy()
{
var modelBuilder = CreateConventionalModelBuilder();
- IForeignKey fk1 = null;
- IForeignKey fk2 = null;
+ IReadOnlyForeignKey fk1 = null;
+ IReadOnlyForeignKey fk2 = null;
modelBuilder.Entity();
modelBuilder.Entity(
@@ -995,8 +995,8 @@ public virtual void Passes_for_compatible_duplicate_foreignKey_names_within_hier
public virtual void Passes_for_compatible_duplicate_foreignKey_names_within_hierarchy_name_configured_explicitly()
{
var modelBuilder = CreateConventionalModelBuilder();
- IForeignKey fk1 = null;
- IForeignKey fk2 = null;
+ IReadOnlyForeignKey fk1 = null;
+ IReadOnlyForeignKey fk2 = null;
modelBuilder.Entity();
modelBuilder.Entity(
diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalBuilderExtensionsTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalBuilderExtensionsTest.cs
index 39d4b0f0a37..66cd0a0f9ff 100644
--- a/test/EFCore.Relational.Tests/Metadata/RelationalBuilderExtensionsTest.cs
+++ b/test/EFCore.Relational.Tests/Metadata/RelationalBuilderExtensionsTest.cs
@@ -841,7 +841,7 @@ public void Can_create_named_sequence()
ValidateNamedSequence(sequence);
}
- private static void ValidateNamedSequence(ISequence sequence)
+ private static void ValidateNamedSequence(IReadOnlySequence sequence)
{
Assert.Equal("Snook", sequence.Name);
Assert.Null(sequence.Schema);
@@ -864,7 +864,7 @@ public void Can_create_schema_named_sequence()
ValidateSchemaNamedSequence(sequence);
}
- private static void ValidateSchemaNamedSequence(ISequence sequence)
+ private static void ValidateSchemaNamedSequence(IReadOnlySequence sequence)
{
Assert.Equal("Snook", sequence.Name);
Assert.Equal("Tasty", sequence.Schema);
@@ -949,7 +949,7 @@ public void Can_create_named_sequence_with_specific_facets_using_nested_closure_
ValidateNamedSpecificSequence(sequence);
}
- private static void ValidateNamedSpecificSequence(ISequence sequence)
+ private static void ValidateNamedSpecificSequence(IReadOnlySequence sequence)
{
Assert.Equal("Snook", sequence.Name);
Assert.Null(sequence.Schema);
@@ -1224,7 +1224,7 @@ private void AssertIsGeneric(ReferenceReferenceBuilder _)
protected virtual ModelBuilder CreateConventionModelBuilder()
=> RelationalTestHelpers.Instance.CreateConventionBuilder();
- private static void ValidateSchemaNamedSpecificSequence(ISequence sequence)
+ private static void ValidateSchemaNamedSpecificSequence(IReadOnlySequence sequence)
{
Assert.Equal("Snook", sequence.Name);
Assert.Equal("Tasty", sequence.Schema);
diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalMetadataBuilderExtensionsTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalMetadataBuilderExtensionsTest.cs
index 72abc764e76..5e22dfd01ea 100644
--- a/test/EFCore.Relational.Tests/Metadata/RelationalMetadataBuilderExtensionsTest.cs
+++ b/test/EFCore.Relational.Tests/Metadata/RelationalMetadataBuilderExtensionsTest.cs
@@ -202,7 +202,7 @@ public void Can_access_relationship()
public void Can_access_check_constraint()
{
var typeBuilder = CreateBuilder().Entity(typeof(Splot), ConfigurationSource.Convention);
- IEntityType entityType = typeBuilder.Metadata;
+ IReadOnlyEntityType entityType = typeBuilder.Metadata;
Assert.NotNull(typeBuilder.HasCheckConstraint("Splew", "s > p"));
Assert.Equal("Splew", entityType.GetCheckConstraints().Single().Name);
diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalMetadataExtensionsTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalMetadataExtensionsTest.cs
index 1952eaa2c28..82a9f0e3712 100644
--- a/test/EFCore.Relational.Tests/Metadata/RelationalMetadataExtensionsTest.cs
+++ b/test/EFCore.Relational.Tests/Metadata/RelationalMetadataExtensionsTest.cs
@@ -359,17 +359,15 @@ public void Can_get_and_set_index_name()
.HasIndex(e => e.Id)
.Metadata;
-#pragma warning disable CS0618 // Type or member is obsolete
- Assert.Equal("IX_Customer_Id", index.GetName());
+ Assert.Equal("IX_Customer_Id", index.GetDatabaseName());
- index.SetName("MyIndex");
+ index.SetDatabaseName("MyIndex");
- Assert.Equal("MyIndex", index.GetName());
+ Assert.Equal("MyIndex", index.GetDatabaseName());
- index.SetName(null);
+ index.SetDatabaseName(null);
- Assert.Equal("IX_Customer_Id", index.GetName());
-#pragma warning restore CS0618 // Type or member is obsolete
+ Assert.Equal("IX_Customer_Id", index.GetDatabaseName());
}
[ConditionalFact]
diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
index c3371f9ad2e..651ee07fbbc 100644
--- a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
+++ b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
@@ -6,6 +6,7 @@
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.TestUtilities;
@@ -24,7 +25,7 @@ public void GetRelationalModel_throws_if_convention_has_not_run()
Assert.Equal(
CoreStrings.ModelNotFinalized("GetRelationalModel"),
Assert.Throws(
- () => modelBuilder.Model.GetRelationalModel()).Message);
+ () => ((IModel)modelBuilder.Model).GetRelationalModel()).Message);
}
[ConditionalTheory]
@@ -36,6 +37,9 @@ public void Can_use_relational_model_with_tables(bool useExplicitMapping, Mappin
{
var model = CreateTestModel(mapToTables: useExplicitMapping, mapping: mapping);
+ var m = model.Model.ToDebugString(MetadataDebugStringOptions.LongDefault);
+ var s = model.ToDebugString(MetadataDebugStringOptions.LongDefault);
+
Assert.Equal(9, model.Model.GetEntityTypes().Count());
Assert.Equal(mapping == Mapping.TPH || !useExplicitMapping ? 3 : 5, model.Tables.Count());
Assert.Empty(model.Views);
@@ -628,7 +632,7 @@ private IRelationalModel CreateTestModel(bool mapToTables = false, bool mapToVie
{
cb.ToTable("ExtraSpecialCustomer", "ExtraSpecialSchema");
}
- });
+ });
modelBuilder.Entity(
ob =>
diff --git a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs
index 04b39120e91..edc94392cc6 100644
--- a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs
+++ b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs
@@ -47,20 +47,37 @@ public void Readonly_relational_metadata_methods_have_expected_name()
public class RelationalApiConsistencyFixture : ApiConsistencyFixtureBase
{
- private static Dictionary _metadataTypes
+ private static Dictionary _metadataTypes
=> new()
{
{
- typeof(IDbFunction),
- (typeof(IMutableDbFunction), typeof(IConventionDbFunction), typeof(IConventionDbFunctionBuilder))
+ typeof(IReadOnlyDbFunction),
+ (typeof(IMutableDbFunction),
+ typeof(IConventionDbFunction),
+ typeof(IConventionDbFunctionBuilder),
+ typeof(IDbFunction))
},
{
- typeof(IDbFunctionParameter),
- (typeof(IMutableDbFunctionParameter), typeof(IConventionDbFunctionParameter),
- typeof(IConventionDbFunctionParameterBuilder))
+ typeof(IReadOnlyDbFunctionParameter),
+ (typeof(IMutableDbFunctionParameter),
+ typeof(IConventionDbFunctionParameter),
+ typeof(IConventionDbFunctionParameterBuilder),
+ typeof(IDbFunctionParameter))
},
- { typeof(ISequence), (typeof(IMutableSequence), typeof(IConventionSequence), typeof(IConventionSequenceBuilder)) },
- { typeof(ICheckConstraint), (typeof(IMutableCheckConstraint), typeof(IConventionCheckConstraint), null) }
+ {
+ typeof(IReadOnlySequence),
+ (typeof(IMutableSequence),
+ typeof(IConventionSequence),
+ typeof(IConventionSequenceBuilder),
+ typeof(ISequence))
+ },
+ {
+ typeof(IReadOnlyCheckConstraint),
+ (typeof(IMutableCheckConstraint),
+ typeof(IConventionCheckConstraint),
+ null,
+ typeof(ICheckConstraint))
+ }
};
public virtual HashSet RelationalMetadataTypes { get; } = new()
@@ -104,22 +121,62 @@ public class RelationalApiConsistencyFixture : ApiConsistencyFixtureBase
};
public override
- List<(Type Type, Type ReadonlyExtensions, Type MutableExtensions, Type ConventionExtensions, Type
- ConventionBuilderExtensions)> MetadataExtensionTypes { get; }
+ List<(Type Type,
+ Type ReadonlyExtensions,
+ Type MutableExtensions,
+ Type ConventionExtensions,
+ Type ConventionBuilderExtensions,
+ Type RuntimeExtensions)> MetadataExtensionTypes { get; }
= new()
{
- (typeof(IModel), typeof(RelationalModelExtensions), typeof(RelationalModelExtensions),
- typeof(RelationalModelExtensions), typeof(RelationalModelBuilderExtensions)),
- (typeof(IEntityType), typeof(RelationalEntityTypeExtensions), typeof(RelationalEntityTypeExtensions),
- typeof(RelationalEntityTypeExtensions), typeof(RelationalEntityTypeBuilderExtensions)),
- (typeof(IKey), typeof(RelationalKeyExtensions), typeof(RelationalKeyExtensions), typeof(RelationalKeyExtensions),
- typeof(RelationalKeyBuilderExtensions)),
- (typeof(IForeignKey), typeof(RelationalForeignKeyExtensions), typeof(RelationalForeignKeyExtensions),
- typeof(RelationalForeignKeyExtensions), typeof(RelationalForeignKeyBuilderExtensions)),
- (typeof(IProperty), typeof(RelationalPropertyExtensions), typeof(RelationalPropertyExtensions),
- typeof(RelationalPropertyExtensions), typeof(RelationalPropertyBuilderExtensions)),
- (typeof(IIndex), typeof(RelationalIndexExtensions), typeof(RelationalIndexExtensions),
- typeof(RelationalIndexExtensions), typeof(RelationalIndexBuilderExtensions))
+ (
+ typeof(IReadOnlyModel),
+ typeof(RelationalModelExtensions),
+ typeof(RelationalModelExtensions),
+ typeof(RelationalModelExtensions),
+ typeof(RelationalModelBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyEntityType),
+ typeof(RelationalEntityTypeExtensions),
+ typeof(RelationalEntityTypeExtensions),
+ typeof(RelationalEntityTypeExtensions),
+ typeof(RelationalEntityTypeBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyKey),
+ typeof(RelationalKeyExtensions),
+ typeof(RelationalKeyExtensions),
+ typeof(RelationalKeyExtensions),
+ typeof(RelationalKeyBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyForeignKey),
+ typeof(RelationalForeignKeyExtensions),
+ typeof(RelationalForeignKeyExtensions),
+ typeof(RelationalForeignKeyExtensions),
+ typeof(RelationalForeignKeyBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyProperty),
+ typeof(RelationalPropertyExtensions),
+ typeof(RelationalPropertyExtensions),
+ typeof(RelationalPropertyExtensions),
+ typeof(RelationalPropertyBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyIndex),
+ typeof(RelationalIndexExtensions),
+ typeof(RelationalIndexExtensions),
+ typeof(RelationalIndexExtensions),
+ typeof(RelationalIndexBuilderExtensions),
+ null
+ )
};
public override HashSet NonVirtualMethods { get; }
@@ -134,9 +191,9 @@ public override
public override HashSet UnmatchedMetadataMethods { get; } = new()
{
- typeof(IDbFunction).GetMethod("get_ReturnEntityType"),
typeof(IMutableSequence).GetMethod("set_ClrType"),
- typeof(RelationalPropertyExtensions).GetMethod(nameof(RelationalPropertyExtensions.FindOverrides)),
+ typeof(RelationalPropertyExtensions).GetRuntimeMethods().Single(m => m.Name == nameof(RelationalPropertyExtensions.FindOverrides)
+ && m.ReturnType == typeof(IReadOnlyAnnotatable)),
typeof(RelationalEntityTypeBuilderExtensions).GetMethod(
nameof(RelationalEntityTypeBuilderExtensions.ExcludeTableFromMigrations))
};
diff --git a/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTest.cs b/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTest.cs
index 89b09da618f..467338fedd5 100644
--- a/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTest.cs
+++ b/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTest.cs
@@ -76,13 +76,13 @@ public void Does_type_mapping_from_btye_array_greater_than_unbounded_max()
private RelationalTypeMapping GetTypeMapping(Type propertyType, int? maxLength = null)
{
- var property = CreateEntityType().AddProperty("MyProp", propertyType);
+ var property = CreateEntityType().AddProperty("MyProp", propertyType);
if (maxLength.HasValue)
{
property.SetMaxLength(maxLength);
}
- return GetMapping(property);
+ return GetMapping((IProperty)property);
}
[ConditionalFact]
@@ -124,10 +124,10 @@ public void Does_type_mapping_from_named_binary_with_no_MaxLength()
private RelationalTypeMapping GetNamedMapping(Type propertyType, string typeName)
{
- var property = CreateEntityType().AddProperty("MyProp", propertyType);
+ var property = CreateEntityType().AddProperty("MyProp", propertyType);
property.SetColumnType(typeName);
- return GetMapping(property);
+ return GetMapping((IProperty)property);
}
[ConditionalFact]
diff --git a/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTestBase.cs b/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTestBase.cs
index d8f8813fa7e..7872c241e9a 100644
--- a/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTestBase.cs
+++ b/test/EFCore.Relational.Tests/Storage/RelationalTypeMapperTestBase.cs
@@ -7,10 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Storage
{
public abstract class RelationalTypeMapperTestBase
{
- protected IMutableEntityType CreateEntityType()
- => CreateModel().FindEntityType(typeof(MyType));
-
- protected IMutableModel CreateModel()
+ protected IMutableEntityType CreateEntityType()
{
var builder = CreateModelBuilder();
@@ -26,9 +23,11 @@ protected IMutableModel CreateModel()
builder.Entity().Property(e => e.PrecisionAndScale).HasPrecision(18, 7);
builder.Entity();
- return builder.Model;
+ return builder.Model.FindEntityType(typeof(TEntity));
}
+ protected IModel CreateModel() => CreateEntityType().Model.FinalizeModel();
+
protected abstract ModelBuilder CreateModelBuilder();
protected class MyType
diff --git a/test/EFCore.Relational.Tests/Update/ModificationCommandComparerTest.cs b/test/EFCore.Relational.Tests/Update/ModificationCommandComparerTest.cs
index 1e602b27f09..30110d7db22 100644
--- a/test/EFCore.Relational.Tests/Update/ModificationCommandComparerTest.cs
+++ b/test/EFCore.Relational.Tests/Update/ModificationCommandComparerTest.cs
@@ -32,19 +32,19 @@ public void Compare_returns_0_only_for_commands_that_are_equal()
var stateManager = new DbContext(optionsBuilder.Options).GetService();
var entry1 = stateManager.GetOrCreateEntry(new object());
- entry1[key] = 1;
+ entry1[(IProperty)key] = 1;
entry1.SetEntityState(EntityState.Added);
var modificationCommandAdded = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, false, null);
modificationCommandAdded.AddEntry(entry1, true);
var entry2 = stateManager.GetOrCreateEntry(new object());
- entry2[key] = 2;
+ entry2[(IProperty)key] = 2;
entry2.SetEntityState(EntityState.Modified);
var modificationCommandModified = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, false, null);
modificationCommandModified.AddEntry(entry2, true);
var entry3 = stateManager.GetOrCreateEntry(new object());
- entry3[key] = 3;
+ entry3[(IProperty)key] = 3;
entry3.SetEntityState(EntityState.Deleted);
var modificationCommandDeleted = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, false, null);
modificationCommandDeleted.AddEntry(entry3, true);
@@ -174,13 +174,13 @@ private void Compare_returns_0_only_for_entries_that_have_same_key_values_generi
var stateManager = new DbContext(optionsBuilder.Options).GetService();
var entry1 = stateManager.GetOrCreateEntry(new object());
- entry1[keyProperty] = value1;
+ entry1[(IProperty)keyProperty] = value1;
entry1.SetEntityState(EntityState.Modified);
var modificationCommand1 = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, false, null);
modificationCommand1.AddEntry(entry1, true);
var entry2 = stateManager.GetOrCreateEntry(new object());
- entry2[keyProperty] = value2;
+ entry2[(IProperty)keyProperty] = value2;
entry2.SetEntityState(EntityState.Modified);
var modificationCommand2 = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, false, null);
modificationCommand2.AddEntry(entry2, true);
diff --git a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs
index 3448d95e745..040b4f1a2f0 100644
--- a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs
+++ b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs
@@ -160,13 +160,13 @@ public void Metadata_types_have_expected_structure()
"\r\n-- Errors: --\r\n" + string.Join(Environment.NewLine, errors));
}
- private static readonly string MetadataNamespace = typeof(IModel).Namespace;
+ private static readonly string MetadataNamespace = typeof(IReadOnlyModel).Namespace;
private static readonly string MetadataBuilderNamespace = typeof(IConventionModelBuilder).Namespace;
- private string ValidateMetadata(KeyValuePair types)
+ private string ValidateMetadata(KeyValuePair types)
{
var readonlyType = types.Key;
- var (mutableType, conventionType, conventionBuilderType) = types.Value;
+ var (mutableType, conventionType, conventionBuilderType, runtimeType) = types.Value;
if (!readonlyType.IsAssignableFrom(mutableType))
{
@@ -179,9 +179,9 @@ private string ValidateMetadata(KeyValuePair types)
}
if (typeof(IAnnotation) != readonlyType
- && typeof(IAnnotatable) != readonlyType)
+ && typeof(IReadOnlyAnnotatable) != readonlyType)
{
- if (!typeof(IAnnotatable).IsAssignableFrom(readonlyType))
+ if (!typeof(IReadOnlyAnnotatable).IsAssignableFrom(readonlyType))
{
return $"{readonlyType.Name} should derive from IAnnotatable";
}
@@ -269,8 +269,7 @@ private string MatchMutable((MethodInfo Readonly, MethodInfo Mutable) methodTupl
{
var (readonlyMethod, mutableMethod) = methodTuple;
- (Type Mutable, Type Convention, Type _) expectedReturnTypes;
- if (Fixture.MetadataTypes.TryGetValue(readonlyMethod.ReturnType, out expectedReturnTypes))
+ if (Fixture.MetadataTypes.TryGetValue(readonlyMethod.ReturnType, out var expectedReturnTypes))
{
if (mutableMethod == null)
{
@@ -502,6 +501,77 @@ private string ValidateConventionBuilderMethods(IReadOnlyList method
return null;
}
+ [ConditionalFact]
+ public void Runtime_metadata_types_have_matching_methods()
+ {
+ var errors =
+ Fixture.MetadataMethods.Select(
+ typeTuple =>
+ from readOnlyMethod in typeTuple.ReadOnly
+ where !Fixture.UnmatchedMetadataMethods.Contains(readOnlyMethod)
+ join runtimeMethod in typeTuple.Runtime
+ on readOnlyMethod.Name equals runtimeMethod?.Name into runtimeGroup
+ from runtimeMethod in runtimeGroup.DefaultIfEmpty()
+ select (readOnlyMethod, runtimeMethod))
+ .SelectMany(m => m.Select(MatchRuntime))
+ .Where(e => e != null)
+ .ToList();
+
+ Assert.False(
+ errors.Count > 0,
+ "\r\n-- Mismatches: --\r\n" + string.Join(Environment.NewLine, errors));
+ }
+
+ private string MatchRuntime((MethodInfo ReadOnly, MethodInfo Runtime) methodTuple)
+ {
+ var (readOnlyMethod, runtimeMethod) = methodTuple;
+
+ Type expectedReturnType;
+ if (readOnlyMethod.ReturnType == typeof(void))
+ {
+ if (runtimeMethod == null)
+ {
+ return "No IRuntime equivalent of "
+ + $"{readOnlyMethod.DeclaringType.Name}.{readOnlyMethod.Name}({Format(readOnlyMethod.GetParameters())})";
+ }
+ }
+ else if (Fixture.MutableMetadataTypes.TryGetValue(readOnlyMethod.ReturnType, out expectedReturnType))
+ {
+ if (runtimeMethod == null)
+ {
+ return "No IRuntime equivalent of "
+ + $"{readOnlyMethod.DeclaringType.Name}.{readOnlyMethod.Name}({Format(readOnlyMethod.GetParameters())})";
+ }
+
+ if (runtimeMethod.ReturnType != expectedReturnType)
+ {
+ return $"{runtimeMethod.DeclaringType.Name}.{runtimeMethod.Name}({Format(runtimeMethod.GetParameters())})"
+ + $" expected to have {expectedReturnType.ShortDisplayName()} return type";
+ }
+ }
+ else
+ {
+ var sequenceType = readOnlyMethod.ReturnType.TryGetSequenceType();
+ if (sequenceType != null
+ && Fixture.MutableMetadataTypes.TryGetValue(sequenceType, out expectedReturnType))
+ {
+ if (runtimeMethod == null)
+ {
+ return "No IRuntime equivalent of "
+ + $"{readOnlyMethod.DeclaringType.Name}.{readOnlyMethod.Name}({Format(readOnlyMethod.GetParameters())})";
+ }
+
+ if (runtimeMethod.ReturnType.TryGetSequenceType() != expectedReturnType)
+ {
+ return $"{runtimeMethod.DeclaringType.Name}.{runtimeMethod.Name}({Format(runtimeMethod.GetParameters())})"
+ + $" expected to have a return type that derives from IEnumerable<{expectedReturnType.Name}>.";
+ }
+ }
+ }
+
+ return null;
+ }
+
[ConditionalFact]
public void Readonly_metadata_methods_have_expected_name()
{
@@ -948,55 +1018,127 @@ protected ApiConsistencyFixtureBase()
#pragma warning restore CS0618 // Type or member is obsolete
};
- public Dictionary MetadataTypes { get; }
+ public Dictionary MetadataTypes { get; }
= new()
{
- { typeof(IModel), (typeof(IMutableModel), typeof(IConventionModel), typeof(IConventionModelBuilder)) },
{
- typeof(IAnnotatable),
- (typeof(IMutableAnnotatable), typeof(IConventionAnnotatable), typeof(IConventionAnnotatableBuilder))
+ typeof(IReadOnlyModel),
+ (typeof(IMutableModel),
+ typeof(IConventionModel),
+ typeof(IConventionModelBuilder),
+ typeof(IModel))
+ },
+ {
+ typeof(IReadOnlyAnnotatable),
+ (typeof(IMutableAnnotatable),
+ typeof(IConventionAnnotatable),
+ typeof(IConventionAnnotatableBuilder),
+ typeof(IAnnotatable))
},
- { typeof(IAnnotation), (typeof(IAnnotation), typeof(IConventionAnnotation), null) },
{
- typeof(IEntityType),
- (typeof(IMutableEntityType), typeof(IConventionEntityType), typeof(IConventionEntityTypeBuilder))
+ typeof(IAnnotation),
+ (typeof(IAnnotation),
+ typeof(IConventionAnnotation),
+ null,
+ null)
},
- { typeof(ITypeBase), (typeof(IMutableTypeBase), typeof(IConventionTypeBase), null) },
- { typeof(IKey), (typeof(IMutableKey), typeof(IConventionKey), typeof(IConventionKeyBuilder)) },
{
- typeof(IForeignKey),
- (typeof(IMutableForeignKey), typeof(IConventionForeignKey), typeof(IConventionForeignKeyBuilder))
+ typeof(IReadOnlyEntityType),
+ (typeof(IMutableEntityType),
+ typeof(IConventionEntityType),
+ typeof(IConventionEntityTypeBuilder),
+ typeof(IEntityType))
},
- { typeof(IIndex), (typeof(IMutableIndex), typeof(IConventionIndex), typeof(IConventionIndexBuilder)) },
- { typeof(IProperty), (typeof(IMutableProperty), typeof(IConventionProperty), typeof(IConventionPropertyBuilder)) },
{
- typeof(INavigation),
- (typeof(IMutableNavigation), typeof(IConventionNavigation), typeof(IConventionNavigationBuilder))
+ typeof(IReadOnlyTypeBase),
+ (typeof(IMutableTypeBase),
+ typeof(IConventionTypeBase),
+ null,
+ typeof(ITypeBase))
},
{
- typeof(ISkipNavigation),
- (typeof(IMutableSkipNavigation), typeof(IConventionSkipNavigation), typeof(IConventionSkipNavigationBuilder))
+ typeof(IReadOnlyKey),
+ (typeof(IMutableKey),
+ typeof(IConventionKey),
+ typeof(IConventionKeyBuilder),
+ typeof(IKey))
},
{
- typeof(IServiceProperty),
- (typeof(IMutableServiceProperty), typeof(IConventionServiceProperty), typeof(IConventionServicePropertyBuilder))
+ typeof(IReadOnlyForeignKey),
+ (typeof(IMutableForeignKey),
+ typeof(IConventionForeignKey),
+ typeof(IConventionForeignKeyBuilder),
+ typeof(IForeignKey))
},
- { typeof(INavigationBase), (typeof(IMutableNavigationBase), typeof(IConventionNavigationBase), null) },
- { typeof(IPropertyBase), (typeof(IMutablePropertyBase), typeof(IConventionPropertyBase), null) }
+ {
+ typeof(IReadOnlyIndex),
+ (typeof(IMutableIndex),
+ typeof(IConventionIndex),
+ typeof(IConventionIndexBuilder),
+ typeof(IIndex))
+ },
+ {
+ typeof(IReadOnlyProperty),
+ (typeof(IMutableProperty),
+ typeof(IConventionProperty),
+ typeof(IConventionPropertyBuilder),
+ typeof(IProperty))
+ },
+ {
+ typeof(IReadOnlyNavigation),
+ (typeof(IMutableNavigation),
+ typeof(IConventionNavigation),
+ typeof(IConventionNavigationBuilder),
+ typeof(INavigation))
+ },
+ {
+ typeof(IReadOnlySkipNavigation),
+ (typeof(IMutableSkipNavigation),
+ typeof(IConventionSkipNavigation),
+ typeof(IConventionSkipNavigationBuilder),
+ typeof(ISkipNavigation))
+ },
+ {
+ typeof(IReadOnlyServiceProperty),
+ (typeof(IMutableServiceProperty),
+ typeof(IConventionServiceProperty),
+ typeof(IConventionServicePropertyBuilder),
+ typeof(IServiceProperty))
+ },
+ {
+ typeof(IReadOnlyNavigationBase),
+ (typeof(IMutableNavigationBase),
+ typeof(IConventionNavigationBase),
+ null,
+ typeof(INavigationBase))
+ },
+ {
+ typeof(IReadOnlyPropertyBase),
+ (typeof(IMutablePropertyBase),
+ typeof(IConventionPropertyBase),
+ null,
+ typeof(IPropertyBase))
+ }
};
public Dictionary MutableMetadataTypes { get; } = new();
public Dictionary ConventionMetadataTypes { get; } = new();
public virtual
- List<(Type Type, Type ReadonlyExtensions, Type MutableExtensions, Type ConventionExtensions, Type
- ConventionBuilderExtensions)> MetadataExtensionTypes { get; }
+ List<(Type Type,
+ Type ReadonlyExtensions,
+ Type MutableExtensions,
+ Type ConventionExtensions,
+ Type ConventionBuilderExtensions,
+ Type RuntimeExtensions)> MetadataExtensionTypes { get; }
= new();
- public List<(IReadOnlyList ReadOnly, IReadOnlyList Mutable, IReadOnlyList Convention,
- IReadOnlyList ConventionBuilder)>
- MetadataMethods { get; }
- = new();
+ public List<(IReadOnlyList ReadOnly,
+ IReadOnlyList Mutable,
+ IReadOnlyList Convention,
+ IReadOnlyList ConventionBuilder,
+ IReadOnlyList Runtime)>
+ MetadataMethods { get; } = new();
protected virtual void Initialize()
{
@@ -1009,33 +1151,42 @@ protected virtual void Initialize()
foreach (var extensionTypeTuple in MetadataExtensionTypes)
{
var type = extensionTypeTuple.Type;
- var (mutableType, conventionType, conventionBuilderType) = MetadataTypes[type];
- var readOnlyMethods = extensionTypeTuple.ReadonlyExtensions.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == type).ToArray();
- var mutableMethods = extensionTypeTuple.MutableExtensions.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == mutableType).ToArray();
- var conventionMethods = extensionTypeTuple.ConventionExtensions.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == conventionType).ToArray();
+ var (mutableType, conventionType, conventionBuilderType, runtimeType) = MetadataTypes[type];
+ var readOnlyMethods = extensionTypeTuple.ReadonlyExtensions?.GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == type).ToArray()
+ ?? new MethodInfo[0];
+ var mutableMethods = extensionTypeTuple.MutableExtensions?.GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == mutableType).ToArray()
+ ?? new MethodInfo[0];
+ var conventionMethods = extensionTypeTuple.ConventionExtensions?.GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == conventionType).ToArray()
+ ?? new MethodInfo[0];
var conventionBuilderMethods = extensionTypeTuple.ConventionBuilderExtensions
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == conventionBuilderType).ToArray();
- MetadataMethods.Add((readOnlyMethods, mutableMethods, conventionMethods, conventionBuilderMethods));
+ .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == conventionBuilderType).ToArray()
+ ?? new MethodInfo[0];
+ var runtimeMethods = extensionTypeTuple.RuntimeExtensions?.GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Where(m => !IsObsolete(m) && m.GetParameters().First().ParameterType == runtimeType).ToArray()
+ ?? new MethodInfo[0];
+ MetadataMethods.Add((readOnlyMethods, mutableMethods, conventionMethods, conventionBuilderMethods, runtimeMethods));
}
}
- protected void AddInstanceMethods(Dictionary types)
+ protected void AddInstanceMethods(Dictionary types)
{
foreach (var typeTuple in types)
{
var readOnlyMethods = typeTuple.Key.GetMethods(PublicInstance)
- .Where(m => !IsObsolete(m)).ToArray();
+ .Where(m => !IsObsolete(m)).ToArray() ?? new MethodInfo[0];
var mutableMethods = typeTuple.Value.Mutable.GetMethods(PublicInstance)
- .Where(m => !IsObsolete(m)).ToArray();
+ .Where(m => !IsObsolete(m)).ToArray() ?? new MethodInfo[0];
var conventionMethods = typeTuple.Value.Convention.GetMethods(PublicInstance)
- .Where(m => !IsObsolete(m)).ToArray();
+ .Where(m => !IsObsolete(m)).ToArray() ?? new MethodInfo[0];
var conventionBuilderMethods = typeTuple.Value.ConventionBuilder?.GetMethods(PublicInstance)
- .Where(m => !IsObsolete(m)).ToArray();
- MetadataMethods.Add((readOnlyMethods, mutableMethods, conventionMethods, conventionBuilderMethods));
+ .Where(m => !IsObsolete(m)).ToArray() ?? new MethodInfo[0];
+ var runtimeMethods = typeTuple.Value.Runtime?.GetMethods(PublicInstance)
+ .Where(m => !IsObsolete(m)).ToArray() ?? new MethodInfo[0];
+ MetadataMethods.Add((readOnlyMethods, mutableMethods, conventionMethods, conventionBuilderMethods, runtimeMethods));
}
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs
index 56abfcbdf80..c285d32fbf4 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs
@@ -7,7 +7,7 @@
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
- public class ForeignKeyStrictComparer : IEqualityComparer, IComparer
+ public class ForeignKeyStrictComparer : IEqualityComparer, IComparer
{
private readonly bool _compareAnnotations;
private readonly bool _compareNavigations;
@@ -18,10 +18,10 @@ public ForeignKeyStrictComparer(bool compareAnnotations = true, bool compareNavi
_compareNavigations = compareNavigations;
}
- public int Compare(IForeignKey x, IForeignKey y)
+ public int Compare(IReadOnlyForeignKey x, IReadOnlyForeignKey y)
=> ForeignKeyComparer.Instance.Compare(x, y);
- public bool Equals(IForeignKey x, IForeignKey y)
+ public bool Equals(IReadOnlyForeignKey x, IReadOnlyForeignKey y)
{
if (x == null)
{
@@ -39,7 +39,7 @@ public bool Equals(IForeignKey x, IForeignKey y)
&& (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
}
- public int GetHashCode(IForeignKey obj)
+ public int GetHashCode(IReadOnlyForeignKey obj)
=> ForeignKeyComparer.Instance.GetHashCode(obj);
}
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
index 5829109468c..dc695eb4a00 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
@@ -28,10 +28,10 @@ public static void ForEach(this IEnumerable @this, Action action)
}
}
- public static IModel Clone(this IModel model)
+ public static IReadOnlyModel Clone(this IReadOnlyModel model)
{
IMutableModel modelClone = new Model();
- var clonedEntityTypes = new Dictionary();
+ var clonedEntityTypes = new Dictionary();
foreach (var entityType in model.GetEntityTypes())
{
var clrType = entityType.ClrType;
@@ -78,7 +78,7 @@ public static IModel Clone(this IModel model)
return modelClone;
}
- private static void CloneProperties(IEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ private static void CloneProperties(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
{
foreach (var property in sourceEntityType.GetDeclaredProperties())
{
@@ -92,7 +92,7 @@ private static void CloneProperties(IEntityType sourceEntityType, IMutableEntity
}
}
- private static void CloneKeys(IEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ private static void CloneKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
{
foreach (var key in sourceEntityType.GetDeclaredKeys())
{
@@ -107,7 +107,7 @@ private static void CloneKeys(IEntityType sourceEntityType, IMutableEntityType t
}
}
- private static void CloneIndexes(IEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ private static void CloneIndexes(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
{
foreach (var index in sourceEntityType.GetDeclaredIndexes())
{
@@ -118,7 +118,7 @@ private static void CloneIndexes(IEntityType sourceEntityType, IMutableEntityTyp
}
}
- private static void CloneForeignKeys(IEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ private static void CloneForeignKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
{
foreach (var foreignKey in sourceEntityType.GetDeclaredForeignKeys())
{
@@ -134,7 +134,7 @@ private static void CloneForeignKeys(IEntityType sourceEntityType, IMutableEntit
}
}
- private static void CloneNavigations(IEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ private static void CloneNavigations(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
{
foreach (var navigation in sourceEntityType.GetDeclaredNavigations())
{
diff --git a/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs
index 9cff0448aba..b1c5898389e 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs
@@ -8,7 +8,7 @@
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
- public class NavigationComparer : IEqualityComparer, IComparer
+ public class NavigationComparer : IEqualityComparer, IComparer
{
private readonly bool _compareAnnotations;
@@ -17,10 +17,10 @@ public NavigationComparer(bool compareAnnotations = true)
_compareAnnotations = compareAnnotations;
}
- public int Compare(INavigation x, INavigation y)
+ public int Compare(IReadOnlyNavigation x, IReadOnlyNavigation y)
=> StringComparer.Ordinal.Compare(x.Name, y.Name);
- public bool Equals(INavigation x, INavigation y)
+ public bool Equals(IReadOnlyNavigation x, IReadOnlyNavigation y)
{
if (x == null)
{
@@ -33,7 +33,7 @@ public bool Equals(INavigation x, INavigation y)
&& (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
}
- public int GetHashCode(INavigation obj)
+ public int GetHashCode(IReadOnlyNavigation obj)
=> obj.Name.GetHashCode();
}
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs
index 64036354a76..16862e2b9f2 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs
@@ -8,7 +8,7 @@
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
- public class PropertyComparer : IEqualityComparer, IComparer
+ public class PropertyComparer : IEqualityComparer, IComparer
{
private readonly bool _compareAnnotations;
@@ -17,10 +17,10 @@ public PropertyComparer(bool compareAnnotations = true)
_compareAnnotations = compareAnnotations;
}
- public int Compare(IProperty x, IProperty y)
+ public int Compare(IReadOnlyProperty x, IReadOnlyProperty y)
=> StringComparer.Ordinal.Compare(x.Name, y.Name);
- public bool Equals(IProperty x, IProperty y)
+ public bool Equals(IReadOnlyProperty x, IReadOnlyProperty y)
{
if (x == null)
{
@@ -40,7 +40,7 @@ public bool Equals(IProperty x, IProperty y)
&& (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
}
- public int GetHashCode(IProperty obj)
+ public int GetHashCode(IReadOnlyProperty obj)
=> obj.Name.GetHashCode();
}
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs
index 7659450c63f..56c7d494bfc 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs
@@ -127,14 +127,6 @@ public IServiceProvider CreateContextServices(IServiceCollection customServices,
public IServiceProvider CreateContextServices(IServiceCollection customServices)
=> ((IInfrastructure)CreateContext(customServices)).Instance;
- public IMutableModel BuildModelFor()
- where TEntity : class
- {
- var builder = CreateConventionBuilder();
- builder.Entity();
- return builder.Model;
- }
-
public IModel Finalize(ModelBuilder modelBuilder, bool skipValidation = false)
{
var contextServices = CreateContextServices();
diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs
index 2c51e9b41e3..88c32467152 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs
@@ -8,7 +8,7 @@
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
- public class TestIndexComparer : IEqualityComparer, IComparer
+ public class TestIndexComparer : IEqualityComparer, IComparer
{
private readonly bool _compareAnnotations;
@@ -17,10 +17,10 @@ public TestIndexComparer(bool compareAnnotations = true)
_compareAnnotations = compareAnnotations;
}
- public int Compare(IIndex x, IIndex y)
+ public int Compare(IReadOnlyIndex x, IReadOnlyIndex y)
=> PropertyListComparer.Instance.Compare(x.Properties, y.Properties);
- public bool Equals(IIndex x, IIndex y)
+ public bool Equals(IReadOnlyIndex x, IReadOnlyIndex y)
{
if (x == null)
{
@@ -34,7 +34,7 @@ public bool Equals(IIndex x, IIndex y)
&& (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
}
- public int GetHashCode(IIndex obj)
+ public int GetHashCode(IReadOnlyIndex obj)
=> PropertyListComparer.Instance.GetHashCode(obj.Properties);
}
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs
index df3219d7f14..cd7e7fbb48e 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs
@@ -8,7 +8,7 @@
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
- public class TestKeyComparer : IEqualityComparer, IComparer
+ public class TestKeyComparer : IEqualityComparer, IComparer
{
private readonly bool _compareAnnotations;
@@ -17,10 +17,10 @@ public TestKeyComparer(bool compareAnnotations = true)
_compareAnnotations = compareAnnotations;
}
- public int Compare(IKey x, IKey y)
+ public int Compare(IReadOnlyKey x, IReadOnlyKey y)
=> PropertyListComparer.Instance.Compare(x.Properties, y.Properties);
- public bool Equals(IKey x, IKey y)
+ public bool Equals(IReadOnlyKey x, IReadOnlyKey y)
{
if (x == null)
{
@@ -33,7 +33,7 @@ public bool Equals(IKey x, IKey y)
&& (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
}
- public int GetHashCode(IKey obj)
+ public int GetHashCode(IReadOnlyKey obj)
=> PropertyListComparer.Instance.GetHashCode(obj.Properties);
}
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs
index cac3768eae8..fa0e09f2684 100644
--- a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs
@@ -42,19 +42,54 @@ public class SqlServerApiConsistencyFixture : ApiConsistencyFixtureBase
};
public override
- List<(Type Type, Type ReadonlyExtensions, Type MutableExtensions, Type ConventionExtensions, Type
- ConventionBuilderExtensions)> MetadataExtensionTypes { get; } = new()
+ List<(Type Type,
+ Type ReadonlyExtensions,
+ Type MutableExtensions,
+ Type ConventionExtensions,
+ Type ConventionBuilderExtensions,
+ Type RuntimeExtensions)> MetadataExtensionTypes { get; }
+ = new()
{
- (typeof(IModel), typeof(SqlServerModelExtensions), typeof(SqlServerModelExtensions),
- typeof(SqlServerModelExtensions), typeof(SqlServerModelBuilderExtensions)),
- (typeof(IEntityType), typeof(SqlServerEntityTypeExtensions), typeof(SqlServerEntityTypeExtensions),
- typeof(SqlServerEntityTypeExtensions), typeof(SqlServerEntityTypeBuilderExtensions)),
- (typeof(IKey), typeof(SqlServerKeyExtensions), typeof(SqlServerKeyExtensions), typeof(SqlServerKeyExtensions),
- typeof(SqlServerKeyBuilderExtensions)),
- (typeof(IProperty), typeof(SqlServerPropertyExtensions), typeof(SqlServerPropertyExtensions),
- typeof(SqlServerPropertyExtensions), typeof(SqlServerPropertyBuilderExtensions)),
- (typeof(IIndex), typeof(SqlServerIndexExtensions), typeof(SqlServerIndexExtensions),
- typeof(SqlServerIndexExtensions), typeof(SqlServerIndexBuilderExtensions))
+ (
+ typeof(IReadOnlyModel),
+ typeof(SqlServerModelExtensions),
+ typeof(SqlServerModelExtensions),
+ typeof(SqlServerModelExtensions),
+ typeof(SqlServerModelBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyEntityType),
+ typeof(SqlServerEntityTypeExtensions),
+ typeof(SqlServerEntityTypeExtensions),
+ typeof(SqlServerEntityTypeExtensions),
+ typeof(SqlServerEntityTypeBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyKey),
+ typeof(SqlServerKeyExtensions),
+ typeof(SqlServerKeyExtensions),
+ typeof(SqlServerKeyExtensions),
+ typeof(SqlServerKeyBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyProperty),
+ typeof(SqlServerPropertyExtensions),
+ typeof(SqlServerPropertyExtensions),
+ typeof(SqlServerPropertyExtensions),
+ typeof(SqlServerPropertyBuilderExtensions),
+ null
+ ),
+ (
+ typeof(IReadOnlyIndex),
+ typeof(SqlServerIndexExtensions),
+ typeof(SqlServerIndexExtensions),
+ typeof(SqlServerIndexExtensions),
+ typeof(SqlServerIndexBuilderExtensions),
+ null
+ )
};
}
}
diff --git a/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs b/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs
index c399d0adcb2..ff286a59a48 100644
--- a/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs
+++ b/test/EFCore.SqlServer.Tests/Design/Internal/SqlServerAnnotationCodeGeneratorTest.cs
@@ -29,7 +29,7 @@ public void GenerateFluentApi_IKey_works_when_clustered()
x.Property("Id");
x.HasKey("Id").IsClustered();
});
- var key = modelBuilder.Model.FindEntityType("Post").GetKeys().Single();
+ var key = (IKey)modelBuilder.Model.FindEntityType("Post").GetKeys().Single();
var result = generator.GenerateFluentApiCalls(key, key.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -51,7 +51,7 @@ public void GenerateFluentApi_IKey_works_when_nonclustered()
x.Property("Id");
x.HasKey("Id").IsClustered(false);
});
- var key = modelBuilder.Model.FindEntityType("Post").GetKeys().Single();
+ var key = (IKey)modelBuilder.Model.FindEntityType("Post").GetKeys().Single();
var result = generator.GenerateFluentApiCalls(key, key.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -75,7 +75,7 @@ public void GenerateFluentApi_IIndex_works_when_clustered()
x.Property("Name");
x.HasIndex("Name").IsClustered();
});
- var index = modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
+ var index = (IIndex)modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
var result = generator.GenerateFluentApiCalls(index, index.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -98,7 +98,7 @@ public void GenerateFluentApi_IIndex_works_when_nonclustered()
x.Property("Name");
x.HasIndex("Name").IsClustered(false);
});
- var index = modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
+ var index = (IIndex)modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
var result = generator.GenerateFluentApiCalls(index, index.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -123,7 +123,7 @@ public void GenerateFluentApi_IIndex_works_with_fillfactor()
x.HasIndex("Name").HasFillFactor(90);
});
- var index = modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
+ var index = (IIndex)modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
var result = generator.GenerateFluentApiCalls(index, index.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -146,8 +146,8 @@ public void GenerateFluentApi_IIndex_works_with_includes()
x.Property("LastName");
x.HasIndex("LastName").IncludeProperties("FirstName");
});
- var index = modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
+ var index = (IIndex)modelBuilder.Model.FindEntityType("Post").GetIndexes().Single();
var result = generator.GenerateFluentApiCalls(index, index.GetAnnotations().ToDictionary(a => a.Name, a => a))
.Single();
@@ -166,7 +166,7 @@ public void GenerateFluentApi_IModel_works_with_identity()
modelBuilder.UseIdentityColumns(seed: 5, increment: 10);
var annotations = modelBuilder.Model.GetAnnotations().ToDictionary(a => a.Name, a => a);
- var result = generator.GenerateFluentApiCalls(modelBuilder.Model, annotations).Single();
+ var result = generator.GenerateFluentApiCalls((IModel)modelBuilder.Model, annotations).Single();
Assert.Equal("UseIdentityColumns", result.Method);
@@ -185,7 +185,7 @@ public void GenerateFluentApi_IProperty_works_with_identity()
var property = modelBuilder.Model.FindEntityType("Post").FindProperty("Id");
var annotations = property.GetAnnotations().ToDictionary(a => a.Name, a => a);
- var result = generator.GenerateFluentApiCalls(property, annotations).Single();
+ var result = generator.GenerateFluentApiCalls((IProperty)property, annotations).Single();
Assert.Equal("UseIdentityColumn", result.Method);
@@ -203,7 +203,7 @@ public void GenerateFluentApi_IModel_works_with_HiLo()
modelBuilder.UseHiLo("HiLoIndexName", "HiLoIndexSchema");
var annotations = modelBuilder.Model.GetAnnotations().ToDictionary(a => a.Name, a => a);
- var result = generator.GenerateFluentApiCalls(modelBuilder.Model, annotations).Single();
+ var result = generator.GenerateFluentApiCalls((IModel)modelBuilder.Model, annotations).Single();
Assert.Equal("UseHiLo", result.Method);
@@ -222,7 +222,7 @@ public void GenerateFluentApi_IProperty_works_with_HiLo()
var property = modelBuilder.Model.FindEntityType("Post").FindProperty("Id");
var annotations = property.GetAnnotations().ToDictionary(a => a.Name, a => a);
- var result = generator.GenerateFluentApiCalls(property, annotations).Single();
+ var result = generator.GenerateFluentApiCalls((IProperty)property, annotations).Single();
Assert.Equal("UseHiLo", result.Method);
@@ -258,7 +258,7 @@ MethodCallCodeFragment GenerateFluentApiCall(string entityTypeName, string prope
{
var property = modelBuilder.Model.FindEntityType(entityTypeName).FindProperty(propertyName);
var annotations = property.GetAnnotations().ToDictionary(a => a.Name, a => a);
- return generator.GenerateFluentApiCalls(property, annotations).SingleOrDefault();
+ return generator.GenerateFluentApiCalls((IProperty)property, annotations).SingleOrDefault();
}
}
diff --git a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerConventionSetBuilderTests.cs b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerConventionSetBuilderTests.cs
index 6e4a93da86d..35b8929bddb 100644
--- a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerConventionSetBuilderTests.cs
+++ b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerConventionSetBuilderTests.cs
@@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
public class SqlServerConventionSetBuilderTests : ConventionSetBuilderTests
{
- public override IModel Can_build_a_model_with_default_conventions_without_DI()
+ public override IReadOnlyModel Can_build_a_model_with_default_conventions_without_DI()
{
var model = base.Can_build_a_model_with_default_conventions_without_DI();
diff --git a/test/EFCore.SqlServer.Tests/Metadata/SqlServerBuilderExtensionsTest.cs b/test/EFCore.SqlServer.Tests/Metadata/SqlServerBuilderExtensionsTest.cs
index 415650d0a4b..50b58d95571 100644
--- a/test/EFCore.SqlServer.Tests/Metadata/SqlServerBuilderExtensionsTest.cs
+++ b/test/EFCore.SqlServer.Tests/Metadata/SqlServerBuilderExtensionsTest.cs
@@ -364,7 +364,7 @@ public void Can_set_use_of_existing_SQL_sequence_for_model()
ValidateSchemaNamedSpecificSequence(sqlServerExtensions.FindSequence("Snook", "Tasty"));
}
- private static void ValidateSchemaNamedSpecificSequence(ISequence sequence)
+ private static void ValidateSchemaNamedSpecificSequence(IReadOnlySequence sequence)
{
Assert.Equal("Snook", sequence.Name);
Assert.Equal("Tasty", sequence.Schema);
diff --git a/test/EFCore.SqlServer.Tests/Migrations/SqlServerMigrationsAnnotationProviderTest.cs b/test/EFCore.SqlServer.Tests/Migrations/SqlServerMigrationsAnnotationProviderTest.cs
index 93f9f9c58d5..ef327a14f0c 100644
--- a/test/EFCore.SqlServer.Tests/Migrations/SqlServerMigrationsAnnotationProviderTest.cs
+++ b/test/EFCore.SqlServer.Tests/Migrations/SqlServerMigrationsAnnotationProviderTest.cs
@@ -22,11 +22,10 @@ public SqlServerMigrationsAnnotationProviderTest()
public void For_property_handles_identity_annotations()
{
var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder();
- var property = modelBuilder.Entity()
- .Property("Id").UseIdentityColumn(2, 3)
- .Metadata;
+ modelBuilder.Entity().Property("Id").UseIdentityColumn(2, 3);
- SqlServerTestHelpers.Instance.Finalize(modelBuilder);
+ var model = SqlServerTestHelpers.Instance.Finalize(modelBuilder);
+ var property = model.FindEntityType(typeof(Entity)).FindProperty("Id");
var migrationAnnotations = _annotations.For(property.GetTableColumnMappings().Single().Column).ToList();
@@ -39,11 +38,11 @@ public void Resolves_column_names_for_Index_with_included_properties()
{
var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder();
modelBuilder.Entity().Property(e => e.IncludedProp).HasColumnName("IncludedColumn");
- var index = modelBuilder.Entity().HasIndex(e => e.IndexedProp).IncludeProperties(e => e.IncludedProp).Metadata;
- SqlServerTestHelpers.Instance.Finalize(modelBuilder);
+ modelBuilder.Entity().HasIndex(e => e.IndexedProp).IncludeProperties(e => e.IncludedProp);
+ var model = SqlServerTestHelpers.Instance.Finalize(modelBuilder);
Assert.Contains(
- _annotations.For(index.GetMappedTableIndexes().Single()),
+ _annotations.For(model.FindEntityType(typeof(Entity)).GetIndexes().Single().GetMappedTableIndexes().Single()),
a => a.Name == SqlServerAnnotationNames.Include && ((string[])a.Value).Contains("IncludedColumn"));
}
diff --git a/test/EFCore.SqlServer.Tests/SqlServerEventIdTest.cs b/test/EFCore.SqlServer.Tests/SqlServerEventIdTest.cs
index b834e88f32c..64cc9b9caa2 100644
--- a/test/EFCore.SqlServer.Tests/SqlServerEventIdTest.cs
+++ b/test/EFCore.SqlServer.Tests/SqlServerEventIdTest.cs
@@ -30,6 +30,7 @@ public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled()
{
{ typeof(IList), () => new List { "Fake1", "Fake2" } },
{ typeof(IProperty), () => property },
+ { typeof(IReadOnlyProperty), () => property },
{ typeof(string), () => "Fake" }
};
diff --git a/test/EFCore.SqlServer.Tests/SqlServerSequenceValueGeneratorTest.cs b/test/EFCore.SqlServer.Tests/SqlServerSequenceValueGeneratorTest.cs
index 8bd63dc49dd..cc07be84632 100644
--- a/test/EFCore.SqlServer.Tests/SqlServerSequenceValueGeneratorTest.cs
+++ b/test/EFCore.SqlServer.Tests/SqlServerSequenceValueGeneratorTest.cs
@@ -79,7 +79,7 @@ private async Task Generates_sequential_values(bool async)
var sequence = ((IMutableModel)new Model()).AddSequence("Foo");
sequence.IncrementBy = blockSize;
- var state = new SqlServerSequenceValueGeneratorState(sequence);
+ var state = new SqlServerSequenceValueGeneratorState((ISequence)sequence);
var generator = new SqlServerSequenceHiLoValueGenerator(
new FakeRawSqlCommandBuilder(blockSize),
@@ -134,7 +134,7 @@ private async Task>> GenerateValuesInMultipleThreads(int
var sequence = ((IMutableModel)new Model()).AddSequence("Foo");
sequence.IncrementBy = blockSize;
- var state = new SqlServerSequenceValueGeneratorState(sequence);
+ var state = new SqlServerSequenceValueGeneratorState((ISequence)sequence);
var executor = new FakeRawSqlCommandBuilder(blockSize);
var sqlGenerator = new SqlServerUpdateSqlGenerator(
@@ -184,7 +184,7 @@ public void Does_not_generate_temp_values()
{
var sequence = ((IMutableModel)new Model()).AddSequence("Foo");
sequence.IncrementBy = 4;
- var state = new SqlServerSequenceValueGeneratorState(sequence);
+ var state = new SqlServerSequenceValueGeneratorState((ISequence)sequence);
var generator = new SqlServerSequenceHiLoValueGenerator(
new FakeRawSqlCommandBuilder(4),
diff --git a/test/EFCore.SqlServer.Tests/SqlServerTypeMapperTest.cs b/test/EFCore.SqlServer.Tests/SqlServerTypeMapperTest.cs
index dba574ac350..31838ee8729 100644
--- a/test/EFCore.SqlServer.Tests/SqlServerTypeMapperTest.cs
+++ b/test/EFCore.SqlServer.Tests/SqlServerTypeMapperTest.cs
@@ -288,13 +288,13 @@ public void Does_non_key_SQL_Server_required_string_mapping(bool? unicode, bool?
[InlineData(null, null)]
public void Does_key_SQL_Server_string_mapping(bool? unicode, bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.IsNullable = false;
property.SetIsUnicode(unicode);
property.SetIsFixedLength(fixedLength);
property.DeclaringEntityType.SetPrimaryKey(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Null(typeMapping.DbType);
Assert.Equal("nvarchar(450)", typeMapping.StoreType);
@@ -316,7 +316,7 @@ private static IRelationalTypeMappingSource CreateTypeMapper()
[InlineData(null, null)]
public void Does_foreign_key_SQL_Server_string_mapping(bool? unicode, bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.IsNullable = false;
property.SetIsUnicode(unicode);
property.SetIsFixedLength(fixedLength);
@@ -324,7 +324,7 @@ public void Does_foreign_key_SQL_Server_string_mapping(bool? unicode, bool? fixe
var pk = property.DeclaringEntityType.SetPrimaryKey(property);
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.Null(typeMapping.DbType);
Assert.Equal("nvarchar(450)", typeMapping.StoreType);
@@ -341,7 +341,7 @@ public void Does_foreign_key_SQL_Server_string_mapping(bool? unicode, bool? fixe
[InlineData(null, null)]
public void Does_required_foreign_key_SQL_Server_string_mapping(bool? unicode, bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.IsNullable = false;
property.SetIsUnicode(unicode);
property.SetIsFixedLength(fixedLength);
@@ -350,7 +350,7 @@ public void Does_required_foreign_key_SQL_Server_string_mapping(bool? unicode, b
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
fkProperty.IsNullable = false;
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.Null(typeMapping.DbType);
Assert.Equal("nvarchar(450)", typeMapping.StoreType);
@@ -367,13 +367,13 @@ public void Does_required_foreign_key_SQL_Server_string_mapping(bool? unicode, b
[InlineData(null, null)]
public void Does_indexed_column_SQL_Server_string_mapping(bool? unicode, bool? fixedLength)
{
- var entityType = CreateEntityType();
+ var entityType = CreateEntityType();
var property = entityType.AddProperty("MyProp", typeof(string));
property.SetIsUnicode(unicode);
property.SetIsFixedLength(fixedLength);
entityType.AddIndex(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Null(typeMapping.DbType);
Assert.Equal("nvarchar(450)", typeMapping.StoreType);
@@ -390,14 +390,13 @@ public void Does_indexed_column_SQL_Server_string_mapping(bool? unicode, bool? f
[InlineData(null, null)]
public void Does_IndexAttribute_column_SQL_Server_string_mapping(bool? unicode, bool? fixedLength)
{
- var model = CreateModel();
- var entityType = model.FindEntityType(typeof(MyTypeWithIndexAttribute));
+ var entityType = CreateEntityType();
var property = entityType.FindProperty("Name");
property.SetIsUnicode(unicode);
property.SetIsFixedLength(fixedLength);
- model.FinalizeModel();
+ entityType.Model.FinalizeModel();
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Null(typeMapping.DbType);
Assert.Equal("nvarchar(450)", typeMapping.StoreType);
@@ -550,13 +549,13 @@ public void Does_non_key_SQL_Server_required_string_mapping_ansi(bool? fixedLeng
[InlineData(null)]
public void Does_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.IsNullable = false;
property.SetIsUnicode(false);
property.SetIsFixedLength(fixedLength);
property.DeclaringEntityType.SetPrimaryKey(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.AnsiString, typeMapping.DbType);
Assert.Equal("varchar(900)", typeMapping.StoreType);
@@ -571,7 +570,7 @@ public void Does_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
[InlineData(null)]
public void Does_foreign_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.SetIsUnicode(false);
property.SetIsFixedLength(fixedLength);
property.IsNullable = false;
@@ -579,7 +578,7 @@ public void Does_foreign_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
var pk = property.DeclaringEntityType.SetPrimaryKey(property);
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.Equal(DbType.AnsiString, typeMapping.DbType);
Assert.Equal("varchar(900)", typeMapping.StoreType);
@@ -594,7 +593,7 @@ public void Does_foreign_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
[InlineData(null)]
public void Does_required_foreign_key_SQL_Server_string_mapping_ansi(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(string));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(string));
property.SetIsUnicode(false);
property.SetIsFixedLength(fixedLength);
property.IsNullable = false;
@@ -603,7 +602,7 @@ public void Does_required_foreign_key_SQL_Server_string_mapping_ansi(bool? fixed
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
fkProperty.IsNullable = false;
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.Equal(DbType.AnsiString, typeMapping.DbType);
Assert.Equal("varchar(900)", typeMapping.StoreType);
@@ -618,13 +617,13 @@ public void Does_required_foreign_key_SQL_Server_string_mapping_ansi(bool? fixed
[InlineData(null)]
public void Does_indexed_column_SQL_Server_string_mapping_ansi(bool? fixedLength)
{
- var entityType = CreateEntityType();
+ var entityType = CreateEntityType();
var property = entityType.AddProperty("MyProp", typeof(string));
property.SetIsUnicode(false);
property.SetIsFixedLength(fixedLength);
entityType.AddIndex(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.AnsiString, typeMapping.DbType);
Assert.Equal("varchar(900)", typeMapping.StoreType);
@@ -639,14 +638,13 @@ public void Does_indexed_column_SQL_Server_string_mapping_ansi(bool? fixedLength
[InlineData(null)]
public void Does_IndexAttribute_column_SQL_Server_string_mapping_ansi(bool? fixedLength)
{
- var model = CreateModel();
- var entityType = model.FindEntityType(typeof(MyTypeWithIndexAttribute));
+ var entityType = CreateEntityType();
var property = entityType.FindProperty("Name");
property.SetIsUnicode(false);
property.SetIsFixedLength(fixedLength);
- model.FinalizeModel();
+ entityType.Model.FinalizeModel();
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.AnsiString, typeMapping.DbType);
Assert.Equal("varchar(900)", typeMapping.StoreType);
@@ -800,7 +798,7 @@ public void Does_non_key_SQL_Server_fixed_length_binary_mapping_with_extreme_val
private RelationalTypeMapping CreateBinaryMapping(string typeName, int? maxLength)
{
- var property = CreateEntityType().AddProperty("MyBinaryProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyBinaryProp", typeof(byte[]));
if (typeName != null)
{
@@ -816,7 +814,7 @@ private RelationalTypeMapping CreateBinaryMapping(string typeName, int? maxLengt
property.SetMaxLength(maxLength);
}
- return CreateTypeMapper().GetMapping(property);
+ return CreateTypeMapper().GetMapping((IProperty)property);
}
[ConditionalTheory]
@@ -824,12 +822,12 @@ private RelationalTypeMapping CreateBinaryMapping(string typeName, int? maxLengt
[InlineData(null)]
public void Does_key_SQL_Server_binary_mapping(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsNullable = false;
property.SetIsFixedLength(fixedLength);
property.DeclaringEntityType.SetPrimaryKey(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.Binary, typeMapping.DbType);
Assert.Equal("varbinary(900)", typeMapping.StoreType);
@@ -842,14 +840,14 @@ public void Does_key_SQL_Server_binary_mapping(bool? fixedLength)
[InlineData(null)]
public void Does_foreign_key_SQL_Server_binary_mapping(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsNullable = false;
property.SetIsFixedLength(fixedLength);
var fkProperty = property.DeclaringEntityType.AddProperty("FK", typeof(byte[]));
var pk = property.DeclaringEntityType.SetPrimaryKey(property);
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.False(typeMapping.IsFixedLength);
Assert.Equal(DbType.Binary, typeMapping.DbType);
@@ -862,7 +860,7 @@ public void Does_foreign_key_SQL_Server_binary_mapping(bool? fixedLength)
[InlineData(null)]
public void Does_required_foreign_key_SQL_Server_binary_mapping(bool? fixedLength)
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsNullable = false;
property.SetIsFixedLength(fixedLength);
var fkProperty = property.DeclaringEntityType.AddProperty("FK", typeof(byte[]));
@@ -870,7 +868,7 @@ public void Does_required_foreign_key_SQL_Server_binary_mapping(bool? fixedLengt
property.DeclaringEntityType.AddForeignKey(fkProperty, pk, property.DeclaringEntityType);
fkProperty.IsNullable = false;
- var typeMapping = CreateTypeMapper().GetMapping(fkProperty);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)fkProperty);
Assert.False(typeMapping.IsFixedLength);
Assert.Equal(DbType.Binary, typeMapping.DbType);
@@ -883,12 +881,12 @@ public void Does_required_foreign_key_SQL_Server_binary_mapping(bool? fixedLengt
[InlineData(null)]
public void Does_indexed_column_SQL_Server_binary_mapping(bool? fixedLength)
{
- var entityType = CreateEntityType();
+ var entityType = CreateEntityType();
var property = entityType.AddProperty("MyProp", typeof(byte[]));
property.SetIsFixedLength(fixedLength);
entityType.AddIndex(property);
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.False(typeMapping.IsFixedLength);
Assert.Equal(DbType.Binary, typeMapping.DbType);
@@ -899,11 +897,11 @@ public void Does_indexed_column_SQL_Server_binary_mapping(bool? fixedLength)
[ConditionalFact]
public void Does_non_key_SQL_Server_rowversion_mapping()
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsConcurrencyToken = true;
property.ValueGenerated = ValueGenerated.OnAddOrUpdate;
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.Binary, typeMapping.DbType);
Assert.Equal("rowversion", typeMapping.StoreType);
@@ -915,12 +913,12 @@ public void Does_non_key_SQL_Server_rowversion_mapping()
[ConditionalFact]
public void Does_non_key_SQL_Server_required_rowversion_mapping()
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsConcurrencyToken = true;
property.ValueGenerated = ValueGenerated.OnAddOrUpdate;
property.IsNullable = false;
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.Binary, typeMapping.DbType);
Assert.Equal("rowversion", typeMapping.StoreType);
@@ -932,10 +930,10 @@ public void Does_non_key_SQL_Server_required_rowversion_mapping()
[ConditionalFact]
public void Does_not_do_rowversion_mapping_for_non_computed_concurrency_tokens()
{
- var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
+ var property = CreateEntityType().AddProperty("MyProp", typeof(byte[]));
property.IsConcurrencyToken = true;
- var typeMapping = CreateTypeMapper().GetMapping(property);
+ var typeMapping = CreateTypeMapper().GetMapping((IProperty)property);
Assert.Equal(DbType.Binary, typeMapping.DbType);
Assert.False(typeMapping.IsFixedLength);
@@ -949,7 +947,7 @@ private RelationalTypeMapping GetTypeMapping(
bool? unicode = null,
bool? fixedLength = null)
{
- var property = CreateEntityType().AddProperty("MyProp", propertyType);
+ var property = CreateEntityType().AddProperty("MyProp", propertyType);
if (nullable.HasValue)
{
@@ -971,7 +969,7 @@ private RelationalTypeMapping GetTypeMapping(
property.SetIsFixedLength(fixedLength);
}
- return CreateTypeMapper().GetMapping(property);
+ return CreateTypeMapper().GetMapping((IProperty)property);
}
[ConditionalFact]
@@ -1010,7 +1008,7 @@ public void Throws_for_unrecognized_property_types()
{
var property = ((IMutableModel)new Model()).AddEntityType("Entity1")
.AddProperty("Strange", typeof(object));
- var ex = Assert.Throws(() => CreateTypeMapper().GetMapping(property));
+ var ex = Assert.Throws(() => CreateTypeMapper().GetMapping((IProperty)property));
Assert.Equal(RelationalStrings.UnsupportedPropertyType("Entity1 (Dictionary)", "Strange", "object"), ex.Message);
Assert.Equal(RelationalStrings.UnsupportedType("object"),
@@ -1103,7 +1101,7 @@ public void Can_map_string_base_type_name_and_size(string typeName)
.HasMaxLength(2018)
.Metadata;
- var mapping = CreateTypeMapper().FindMapping(property);
+ var mapping = CreateTypeMapper().FindMapping((IProperty)property);
Assert.Same(typeof(string), mapping.ClrType);
Assert.Equal(2018, mapping.Size);
@@ -1126,7 +1124,7 @@ public void Can_map_binary_base_type_name_and_size(string typeName)
.HasMaxLength(2018)
.Metadata;
- var mapping = CreateTypeMapper().FindMapping(property);
+ var mapping = CreateTypeMapper().FindMapping((IProperty)property);
Assert.Same(typeof(byte[]), mapping.ClrType);
Assert.Equal(2018, mapping.Size);
diff --git a/test/EFCore.SqlServer.Tests/SqlServerValueGeneratorCacheTest.cs b/test/EFCore.SqlServer.Tests/SqlServerValueGeneratorCacheTest.cs
index 464980fceab..a9bee4a5182 100644
--- a/test/EFCore.SqlServer.Tests/SqlServerValueGeneratorCacheTest.cs
+++ b/test/EFCore.SqlServer.Tests/SqlServerValueGeneratorCacheTest.cs
@@ -127,7 +127,7 @@ public void Block_size_is_obtained_from_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(10, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(10, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -145,7 +145,7 @@ public void Block_size_is_obtained_from_named_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(10, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(10, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -163,7 +163,7 @@ public void Block_size_is_obtained_from_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(10, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(10, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -181,7 +181,7 @@ public void Block_size_is_obtained_from_named_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(10, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(10, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -200,7 +200,7 @@ public void Block_size_is_obtained_from_specified_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(11, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(11, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -222,7 +222,7 @@ public void Non_positive_block_sizes_are_not_allowed()
Assert.StartsWith(
CoreStrings.HiLoBadBlockSize,
Assert.Throws(
- () => cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy).Message);
+ () => cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy).Message);
}
[ConditionalFact]
@@ -241,7 +241,7 @@ public void Block_size_is_obtained_from_specified_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal(11, cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.IncrementBy);
+ Assert.Equal(11, cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.IncrementBy);
}
[ConditionalFact]
@@ -259,7 +259,7 @@ public void Sequence_name_is_obtained_from_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("EntityFrameworkHiLoSequence", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("EntityFrameworkHiLoSequence", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -277,7 +277,7 @@ public void Sequence_name_is_obtained_from_named_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -295,7 +295,7 @@ public void Sequence_name_is_obtained_from_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("EntityFrameworkHiLoSequence", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("EntityFrameworkHiLoSequence", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -313,7 +313,7 @@ public void Sequence_name_is_obtained_from_named_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -332,7 +332,7 @@ public void Sequence_name_is_obtained_from_specified_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -351,7 +351,7 @@ public void Sequence_name_is_obtained_from_specified_model_default_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
}
[ConditionalFact]
@@ -369,8 +369,8 @@ public void Schema_qualified_sequence_name_is_obtained_from_named_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
- Assert.Equal("R", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Schema);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
+ Assert.Equal("R", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Schema);
}
[ConditionalFact]
@@ -388,8 +388,8 @@ public void Schema_qualified_sequence_name_is_obtained_from_named_model_default_
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
- Assert.Equal("R", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Schema);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
+ Assert.Equal("R", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Schema);
}
[ConditionalFact]
@@ -408,8 +408,8 @@ public void Schema_qualified_sequence_name_is_obtained_from_specified_sequence()
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
- Assert.Equal("R", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Schema);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
+ Assert.Equal("R", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Schema);
}
[ConditionalFact]
@@ -428,8 +428,8 @@ public void Schema_qualified_sequence_name_is_obtained_from_specified_model_defa
var cache = new SqlServerValueGeneratorCache(new ValueGeneratorCacheDependencies());
- Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Name);
- Assert.Equal("R", cache.GetOrAddSequenceState(property, CreateConnection()).Sequence.Schema);
+ Assert.Equal("DaneelOlivaw", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Name);
+ Assert.Equal("R", cache.GetOrAddSequenceState((IProperty)property, CreateConnection()).Sequence.Schema);
}
protected virtual ModelBuilder CreateConventionModelBuilder()
diff --git a/test/EFCore.Sqlite.Tests/Metadata/Conventions/SqliteConventionSetBuilderTests.cs b/test/EFCore.Sqlite.Tests/Metadata/Conventions/SqliteConventionSetBuilderTests.cs
index d5e38c3bb56..28bfc0d8ba4 100644
--- a/test/EFCore.Sqlite.Tests/Metadata/Conventions/SqliteConventionSetBuilderTests.cs
+++ b/test/EFCore.Sqlite.Tests/Metadata/Conventions/SqliteConventionSetBuilderTests.cs
@@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
public class SqliteConventionSetBuilderTests : ConventionSetBuilderTests
{
- public override IModel Can_build_a_model_with_default_conventions_without_DI()
+ public override IReadOnlyModel Can_build_a_model_with_default_conventions_without_DI()
{
var model = base.Can_build_a_model_with_default_conventions_without_DI();
diff --git a/test/EFCore.Sqlite.Tests/Migrations/SqliteMigrationAnnotationProviderTest.cs b/test/EFCore.Sqlite.Tests/Migrations/SqliteMigrationAnnotationProviderTest.cs
index ba708970627..ada2276997d 100644
--- a/test/EFCore.Sqlite.Tests/Migrations/SqliteMigrationAnnotationProviderTest.cs
+++ b/test/EFCore.Sqlite.Tests/Migrations/SqliteMigrationAnnotationProviderTest.cs
@@ -19,7 +19,7 @@ public class SqliteMigrationAnnotationProviderTest
[ConditionalFact]
public void Does_not_add_Autoincrement_for_OnAdd_integer_property_non_key()
{
- var property = _modelBuilder.Entity