diff --git a/src/EFCore/ChangeTracking/ChangeTracker.cs b/src/EFCore/ChangeTracking/ChangeTracker.cs
index da8aa7835b4..25d68233002 100644
--- a/src/EFCore/ChangeTracking/ChangeTracker.cs
+++ b/src/EFCore/ChangeTracking/ChangeTracker.cs
@@ -220,7 +220,7 @@ public virtual bool HasChanges()
///
public virtual void DetectChanges()
{
- if ((string)_model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true")
+ if (!((Model)_model).SkipDetectChanges)
{
ChangeDetector.DetectChanges(StateManager);
}
diff --git a/src/EFCore/ChangeTracking/CollectionEntry.cs b/src/EFCore/ChangeTracking/CollectionEntry.cs
index c27e6332479..96af0410be0 100644
--- a/src/EFCore/ChangeTracking/CollectionEntry.cs
+++ b/src/EFCore/ChangeTracking/CollectionEntry.cs
@@ -63,7 +63,7 @@ private void LocalDetectChanges()
var context = InternalEntry.StateManager.Context;
var changeDetector = context.ChangeTracker.AutoDetectChangesEnabled
- && (string)context.Model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true"
+ && !((Model)context.Model).SkipDetectChanges
? context.GetDependencies().ChangeDetector
: null;
diff --git a/src/EFCore/ChangeTracking/EntityEntry.cs b/src/EFCore/ChangeTracking/EntityEntry.cs
index 5e932a4cebf..16d917f2ce7 100644
--- a/src/EFCore/ChangeTracking/EntityEntry.cs
+++ b/src/EFCore/ChangeTracking/EntityEntry.cs
@@ -102,7 +102,7 @@ public virtual EntityState State
///
public virtual void DetectChanges()
{
- if ((string)Context.Model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true")
+ if (!((Model)Context.Model).SkipDetectChanges)
{
Context.GetDependencies().ChangeDetector.DetectChanges(InternalEntry);
}
diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs
index c6f90dfafd1..64118aa2399 100644
--- a/src/EFCore/ChangeTracking/Internal/StateManager.cs
+++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs
@@ -993,7 +993,7 @@ public virtual void CascadeDelete(InternalEntityEntry entry, bool force, IEnumer
if (!_changeDetectorInitialized)
{
_changeDetector = Context.ChangeTracker.AutoDetectChangesEnabled
- && (string)Context.Model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true"
+ && !((Model)Context.Model).SkipDetectChanges
? Context.GetDependencies().ChangeDetector
: null;
_changeDetectorInitialized = true;
diff --git a/src/EFCore/ChangeTracking/ReferenceEntry.cs b/src/EFCore/ChangeTracking/ReferenceEntry.cs
index 93cc1cb5010..eddcbcb4f4f 100644
--- a/src/EFCore/ChangeTracking/ReferenceEntry.cs
+++ b/src/EFCore/ChangeTracking/ReferenceEntry.cs
@@ -70,7 +70,7 @@ private void LocalDetectChanges()
{
var context = InternalEntry.StateManager.Context;
if (context.ChangeTracker.AutoDetectChangesEnabled
- && (string)context.Model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true")
+ && !((Model)context.Model).SkipDetectChanges)
{
context.GetDependencies().ChangeDetector.DetectChanges(target);
}
diff --git a/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs
index 0a4ae96eefe..731d551f4af 100644
--- a/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs
+++ b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs
@@ -41,7 +41,10 @@ public virtual void ProcessModelFinalizing(
}
}
- modelBuilder.HasAnnotation(CoreAnnotationNames.SkipDetectChangesAnnotation, "true");
+ if (modelBuilder.Metadata is Model model)
+ {
+ model.SetSkipDetectChanges(true);
+ }
}
}
}
diff --git a/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs b/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs
index e170f185413..7dc0c460b3f 100644
--- a/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs
+++ b/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs
@@ -257,14 +257,6 @@ public static class CoreAnnotationNames
///
public const string AmbiguousField = "BackingFieldConvention:AmbiguousField";
- ///
- /// 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 const string SkipDetectChangesAnnotation = "ChangeDetector.SkipDetectChanges";
-
///
/// 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
@@ -315,7 +307,6 @@ public static class CoreAnnotationNames
AmbiguousNavigations,
DuplicateServiceProperties,
AmbiguousField,
- SkipDetectChangesAnnotation,
SkipChangeTrackingStrategyValidationAnnotation
};
}
diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs
index c19e5eb98e4..e5274c68234 100644
--- a/src/EFCore/Metadata/Internal/Model.cs
+++ b/src/EFCore/Metadata/Internal/Model.cs
@@ -61,6 +61,8 @@ private readonly Dictionary _ignoredTypeNames
private readonly Dictionary _sharedTypes =
new Dictionary { { DefaultPropertyBagType, ConfigurationSource.Convention } };
+ private bool? _skipDetectChanges;
+
///
/// 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
@@ -989,6 +991,31 @@ private IModel MakeReadonly()
public virtual PropertyInfo FindIndexerPropertyInfo([NotNull] Type type)
=> _indexerPropertyInfoMap.GetOrAdd(type, type.FindIndexerProperty());
+ ///
+ /// 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 SkipDetectChanges
+ {
+ get => _skipDetectChanges ?? false;
+ set => SetSkipDetectChanges(value);
+ }
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in 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? SetSkipDetectChanges(bool? skipDetectChanges)
+ {
+ _skipDetectChanges = skipDetectChanges;
+
+ return skipDetectChanges;
+ }
+
///
/// 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/Update/Internal/UpdateAdapter.cs b/src/EFCore/Update/Internal/UpdateAdapter.cs
index d84674ff158..963e5c90907 100644
--- a/src/EFCore/Update/Internal/UpdateAdapter.cs
+++ b/src/EFCore/Update/Internal/UpdateAdapter.cs
@@ -115,7 +115,7 @@ public virtual IEnumerable Entries
///
public virtual void DetectChanges()
{
- if ((string)_stateManager.Model[CoreAnnotationNames.SkipDetectChangesAnnotation] != "true")
+ if (!((Model)_stateManager.Model).SkipDetectChanges)
{
_changeDetector.DetectChanges(_stateManager);
}