Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/EFCore/ChangeTracking/ChangeTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,44 @@ public virtual IEnumerable<EntityEntry<TEntity>> Entries<TEntity>()
.Select(e => new EntityEntry<TEntity>(e));
}

/// <summary>
/// Returns tracked entities that are in a given state from a fast cache.
/// </summary>
/// <param name="added">Entities in EntityState.Added state</param>
/// <param name="modified">Entities in Modified.Added state</param>
/// <param name="deleted">Entities in Modified.Deleted state</param>
/// <param name="unchanged">Entities in Modified.Unchanged state</param>
Comment on lines +222 to +224
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML doc parameter descriptions for modified, deleted, and unchanged reference non-existent states like "Modified.Added"/"Modified.Deleted". These should refer to EntityState.Modified, EntityState.Deleted, and EntityState.Unchanged (and ideally use <see cref="EntityState.*" />).

Suggested change
/// <param name="modified">Entities in Modified.Added state</param>
/// <param name="deleted">Entities in Modified.Deleted state</param>
/// <param name="unchanged">Entities in Modified.Unchanged state</param>
/// <param name="modified">Entities in the <see cref="EntityState.Modified" /> state.</param>
/// <param name="deleted">Entities in the <see cref="EntityState.Deleted" /> state.</param>
/// <param name="unchanged">Entities in the <see cref="EntityState.Unchanged" /> state.</param>

Copilot uses AI. Check for mistakes.
/// <returns>An entry for each entity that matched the search criteria.</returns>
public virtual IEnumerable<EntityEntry> GetEntriesForState(
bool added = false,
bool modified = false,
bool deleted = false,
bool unchanged = false)
Comment on lines +226 to +230
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests were found covering the new public ChangeTracker.GetEntriesForState* APIs. Adding tests for each state flag combination (and for behavior when AutoDetectChangesEnabled is true/false) would help prevent regressions, especially since this method intentionally differs from Entries() behavior.

Copilot generated this review using guidance from repository custom instructions.
{
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetEntriesForState doesn't call TryDetectChanges() (unlike Entries()/Entries<TEntity>() above). With snapshot tracking this can return stale results unless DetectChanges() was run elsewhere. Either call TryDetectChanges() here or document explicitly that this is a "no DetectChanges" fast-path and may not reflect up-to-date state.

Suggested change
{
{
TryDetectChanges();

Copilot uses AI. Check for mistakes.
return StateManager.GetEntriesForState(added, modified, deleted, unchanged)
.Select(e => new EntityEntry(e));
}
Comment on lines +218 to +234
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for this method is incomplete and doesn't follow EF Core documentation conventions. It should include:

  1. A proper summary describing what the method does and when to use it
  2. Remarks section with links to documentation using <see href="https://aka.ms/efcore-docs-*"> format
  3. Proper parameter descriptions using <param> tags
  4. Better description of the state parameters (currently says "Modified.Added" and "Modified.Deleted" which appear to be copy-paste errors - should be "EntityState.Modified" and "EntityState.Deleted")

Compare with the existing Entries() method documentation at lines 183-216 for the expected format.

Copilot uses AI. Check for mistakes.

/// <summary>
/// Returns tracked entities that are in a given state from a fast cache.
/// </summary>
/// <param name="added">Entities in EntityState.Added state</param>
/// <param name="modified">Entities in Modified.Added state</param>
/// <param name="deleted">Entities in Modified.Deleted state</param>
/// <param name="unchanged">Entities in Modified.Unchanged state</param>
/// <returns>An entry for each entity that matched the search criteria.</returns>
public virtual IEnumerable<EntityEntry<TEntity>> GetEntriesForState<TEntity>(
bool added = false,
bool modified = false,
bool deleted = false,
bool unchanged = false)
where TEntity : class
{
return StateManager.GetEntriesForState(added, modified, deleted, unchanged)
.Where(e => e.Entity is TEntity)
.Select(e => new EntityEntry<TEntity>(e));
}
Comment on lines +236 to +254
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for this method has copy-paste errors in parameter descriptions. Line 222 says "Entities in Modified.Added state" when it should say "Entities in EntityState.Modified state". Line 223 says "Entities in Modified.Deleted state" when it should say "Entities in EntityState.Deleted state". Line 224 says "Entities in Modified.Unchanged state" when it should say "Entities in EntityState.Unchanged state".

Copilot uses AI. Check for mistakes.
Comment on lines +218 to +254
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description claims "Added test for testing ChangeTracker.GetEntries(EntityState)" but no tests for the new GetEntriesForState methods are included in this PR. The new public API methods ChangeTracker.GetEntriesForState() and ChangeTracker.GetEntriesForState() lack test coverage. Tests should be added to verify the behavior of these methods, including:

  • Filtering by different entity states (added, modified, deleted, unchanged)
  • Filtering by combinations of states
  • Generic vs non-generic versions
  • Edge cases (no entities, all entities in same state, etc.)

Copilot uses AI. Check for mistakes.

private void TryDetectChanges()
{
if (AutoDetectChangesEnabled)
Expand Down
83 changes: 83 additions & 0 deletions src/EFCore/ChangeTracking/EntityEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,65 @@ public virtual void Reload()
public virtual async Task ReloadAsync(CancellationToken cancellationToken = default)
=> Reload(await GetDatabaseValuesAsync(cancellationToken).ConfigureAwait(false));

/// <summary>
/// Reloads the entity from the database using the specified <see cref="MergeOption" />.
/// </summary>
/// <remarks>
/// <para>
/// The behavior of this method depends on the <see cref="MergeOption" /> specified:
/// </para>
/// <para>
/// <see cref="MergeOption.OverwriteChanges" />: Overwrites both current and original property values with values from the database.
/// The entity will be in the <see cref="EntityState.Unchanged" /> state after calling this method.
/// </para>
/// <para>
/// <see cref="MergeOption.PreserveChanges" />: Updates original property values with values from the database,
/// but preserves any local modifications to current values. Modified properties remain modified with their current values.
/// </para>
/// <para>
/// If the entity does not exist in the database, the entity will be <see cref="EntityState.Detached" />.
/// Calling Reload on an <see cref="EntityState.Added" /> entity that does not exist in the database is a no-op.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see> for more information and
/// examples.
/// </para>
/// </remarks>
/// <param name="mergeOption">The merge option controlling how database values are applied to the entity.</param>
public virtual void Reload(MergeOption mergeOption)
=> Reload(GetDatabaseValues(), mergeOption);

/// <summary>
/// Reloads the entity from the database using the specified <see cref="MergeOption" />.
/// </summary>
/// <remarks>
/// <para>
/// The behavior of this method depends on the <see cref="MergeOption" /> specified:
/// </para>
/// <para>
/// <see cref="MergeOption.OverwriteChanges" />: Overwrites both current and original property values with values from the database.
/// The entity will be in the <see cref="EntityState.Unchanged" /> state after calling this method.
/// </para>
/// <para>
/// <see cref="MergeOption.PreserveChanges" />: Updates original property values with values from the database,
/// but preserves any local modifications to current values. Modified properties remain modified with their current values.
/// </para>
/// <para>
/// If the entity does not exist in the database, the entity will be <see cref="EntityState.Detached" />.
/// Calling Reload on an <see cref="EntityState.Added" /> entity that does not exist in the database is a no-op.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see> for more information and
/// examples.
/// </para>
/// </remarks>
/// <param name="mergeOption">The merge option controlling how database values are applied to the entity.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public virtual async Task ReloadAsync(MergeOption mergeOption, CancellationToken cancellationToken = default)
=> Reload(await GetDatabaseValuesAsync(cancellationToken).ConfigureAwait(false), mergeOption);

private void Reload(PropertyValues? storeValues)
{
if (storeValues == null)
Expand All @@ -697,6 +756,30 @@ private void Reload(PropertyValues? storeValues)
State = EntityState.Unchanged;
}
}
private void Reload(PropertyValues? storeValues, MergeOption mergeOption)
{
if (storeValues == null)
{
if (State != EntityState.Added)
{
State = EntityState.Deleted;
State = EntityState.Detached;
}
}
else
{
foreach (var property in Metadata.GetProperties())
{
var value = storeValues[property];
InternalEntry.ReloadValue(property, value, mergeOption, updateEntityState: false);
}

if (mergeOption == MergeOption.OverwriteChanges)
{
State = EntityState.Unchanged;
}
}
}
Comment on lines +759 to +782
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Reload(PropertyValues, MergeOption) method only iterates over properties (line 771) but doesn't handle navigations. The existing Reload(PropertyValues) method (lines 742-758) uses PropertyValues.SetValues() which handles both properties and navigations. Consider whether navigations should also be refreshed, particularly for owned entities and complex types. If navigations should not be refreshed, this should be documented in the method's XML comments.

Copilot uses AI. Check for mistakes.

[field: AllowNull, MaybeNull]
private IEntityFinder Finder
Expand Down
32 changes: 32 additions & 0 deletions src/EFCore/ChangeTracking/Internal/InternalEntryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,38 @@ private void DetectChanges(IComplexProperty complexProperty)
}
}

/// <summary>
/// Refreshes the property value with the value from the database
/// </summary>
/// <param name="propertyBase">Property</param>
/// <param name="value">New value from database</param>
/// <param name="mergeOption">MergeOption</param>
/// <param name="updateEntityState">Sets the EntityState to Unchanged if MergeOption.OverwriteChanges else calls ChangeDetector to determine changes</param>
public virtual void ReloadValue(IPropertyBase propertyBase, object? value, MergeOption mergeOption, bool updateEntityState)
{
var property = (IProperty)propertyBase;
EnsureOriginalValues();
Comment on lines +1008 to +1011
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReloadValue accepts IPropertyBase but immediately casts it to IProperty, which will throw InvalidCastException if a non-scalar property (e.g. complex property) is ever passed. Consider changing the parameter type to IProperty, or add a guard with a clear exception/debug assert to make incorrect usage fail deterministically.

Copilot uses AI. Check for mistakes.
bool isModified = IsModified(property);
_originalValues.SetValue(property, value, -1);
if (mergeOption == MergeOption.OverwriteChanges || !isModified)
{
SetProperty(propertyBase, value, isMaterialization: true, setModified: false);
}

if (updateEntityState)
{
if (mergeOption == MergeOption.OverwriteChanges)
{
SetEntityState(EntityState.Unchanged);
}
else if (StateManager is StateManager stateManager
&& stateManager.ChangeDetector is ChangeDetector changeDetector)
{
changeDetector.DetectValueChange(this, property);
}
}
}
Comment on lines 1001 to 1031
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The InternalEntryBase.ReloadValue method lacks the required XML documentation comment for internal APIs. According to EF Core coding guidelines, types in .Internal namespaces require this standard comment on ALL members:

/// <summary>
///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
///     the same compatibility standards as public APIs. It may be changed or removed without notice in
///     any release. You should only use it directly in your code with extreme caution and knowing that
///     doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>

The current documentation is insufficient for an internal API.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines 1008 to 1031
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ReloadValue method calls ChangeDetector.DetectValueChange for individual properties (line 1021), but this may be inefficient when reloading many properties. When updateEntityState is true and mergeOption is PreserveChanges, DetectValueChange is called for every property individually. Consider batching these calls or using a more efficient approach, especially since this is in the hot path during query materialization with Refresh.

Copilot uses AI. Check for mistakes.

private void ReorderOriginalComplexCollectionEntries(IComplexProperty complexProperty, IList? newOriginalCollection)
{
Check.DebugAssert(HasOriginalValuesSnapshot, "This should only be called when original values are present");
Expand Down
81 changes: 81 additions & 0 deletions src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3099,6 +3099,87 @@ public static IQueryable<TEntity> AsTracking<TEntity>(

#endregion

#region Refreshing

internal static readonly MethodInfo RefreshMethodInfo
= typeof(EntityFrameworkQueryableExtensions).GetMethod(
nameof(Refresh), [typeof(IQueryable<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(MergeOption)])!;


Comment on lines +3105 to +3108
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RefreshMethodInfo is retrieved via GetMethod(...) with Type.MakeGenericMethodParameter(0), which is inconsistent with patterns used elsewhere in this file (e.g. ExecuteDeleteMethodInfo uses GetDeclaredMethod). Consider switching to the same approach (get the declared method and then use GetGenericMethodDefinition() if needed) to reduce reflection complexity and improve maintainability.

Suggested change
= typeof(EntityFrameworkQueryableExtensions).GetMethod(
nameof(Refresh), [typeof(IQueryable<>).MakeGenericType(Type.MakeGenericMethodParameter(0)), typeof(MergeOption)])!;
= typeof(EntityFrameworkQueryableExtensions).GetTypeInfo()
.GetDeclaredMethod(nameof(Refresh))!
.GetGenericMethodDefinition();

Copilot uses AI. Check for mistakes.
/// <summary>
/// Specifies that the current Entity Framework LINQ query should refresh already loaded objects with the specified merge option.
/// </summary>
/// <typeparam name="T">The type of entity being queried.</typeparam>
/// <param name="source">The source query.</param>
/// <param name="mergeOption">The MergeOption</param>
/// <returns>A new query annotated with the given tag.</returns>
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <returns> XML doc for Refresh says "annotated with the given tag", which looks like it was copied from TagWith and doesn't describe Refresh. Please update it to describe the refresh behavior instead.

Suggested change
/// <returns>A new query annotated with the given tag.</returns>
/// <returns>A new query that refreshes already loaded entities according to the specified merge option.</returns>

Copilot uses AI. Check for mistakes.
public static IQueryable<T> Refresh<T>(
this IQueryable<T> source,
[NotParameterized] MergeOption mergeOption)
{
if (HasNonTrackingOrIgnoreAutoIncludes(source.Expression))
{
throw new InvalidOperationException(CoreStrings.RefreshNonTrackingQuery);
}
Comment on lines +3120 to +3123
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refresh relies on HasNonTrackingOrIgnoreAutoIncludes(source.Expression) to enforce tracking. This only catches explicit AsNoTracking*() calls; it won't catch queries that are non-tracking because ChangeTracker.QueryTrackingBehavior is configured globally, making Refresh a silent no-op instead of throwing.

Copilot uses AI. Check for mistakes.

if (HasMultipleMergeOptions(source.Expression))
{
throw new InvalidOperationException(CoreStrings.RefreshMultipleMergeOptions);
}
return
source.Provider is EntityQueryProvider
? source.Provider.CreateQuery<T>(
Expression.Call(
instance: null,
method: RefreshMethodInfo.MakeGenericMethod(typeof(T)),
arg0: source.Expression,
arg1: Expression.Constant(mergeOption)))
: source;
}
Comment on lines +3109 to +3138
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for the Refresh method is incomplete and doesn't follow EF Core documentation conventions. It should include:

  1. A proper remarks section explaining how this method interacts with the change tracker and when to use it
  2. Links to documentation using the <see href="https://aka.ms/efcore-docs-*"> format (not hardcoded learn.microsoft.com URLs)
  3. An example showing how to use this method
  4. Better parameter documentation - the current "The MergeOption" description is not helpful
  5. The return value description says "A new query annotated with the given tag" which is incorrect (copy-pasted from another method) - should describe that it returns a query that will refresh tracked entities when materialized

Copilot uses AI. Check for mistakes.

private static bool HasNonTrackingOrIgnoreAutoIncludes(Expression expression)
{
Expression? current = expression;
while (current is MethodCallExpression call)
{
var method = call.Method;
if (method.DeclaringType == typeof(EntityFrameworkQueryableExtensions))
{
var name = method.Name;
if (name == nameof(AsNoTracking)
|| name == nameof(AsNoTrackingWithIdentityResolution)
|| name == nameof(IgnoreAutoIncludes))
Comment on lines +3150 to +3151
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HasNonTrackingOrIgnoreAutoIncludes treats IgnoreAutoIncludes() as equivalent to non-tracking and causes Refresh to throw RefreshNonTrackingQuery. Ignoring auto-includes doesn't disable tracking, so this check (or the exception message) should be adjusted.

Suggested change
|| name == nameof(AsNoTrackingWithIdentityResolution)
|| name == nameof(IgnoreAutoIncludes))
|| name == nameof(AsNoTrackingWithIdentityResolution))

Copilot uses AI. Check for mistakes.
{
return true;
}
}

current = call.Arguments.Count > 0 ? call.Arguments[0] : null;
}

return false;
}

private static bool HasMultipleMergeOptions(Expression expression)
{
Expression? current = expression;
while (current is MethodCallExpression call)
{
var method = call.Method;
if (method.DeclaringType == typeof(EntityFrameworkQueryableExtensions)
&& method.Name == nameof(Refresh))
{
return true;
}

current = call.Arguments.Count > 0 ? call.Arguments[0] : null;
}

return false;
}

#endregion

#region Tagging

/// <summary>
Expand Down
27 changes: 27 additions & 0 deletions src/EFCore/MergeOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore;

/// <summary>
/// The different ways that new objects loaded from the database can be merged with existing objects already in memory.
/// </summary>
public enum MergeOption
{
/// <summary>
/// Will only append new (top level-unique) rows. This is the default behavior.
/// </summary>
AppendOnly = 0,

/// <summary>
/// The incoming values for this row will be written to both the current value and
/// the original value versions of the data for each column.
/// </summary>
OverwriteChanges = 1,

/// <summary>
/// The incoming values for this row will be written to the original value version
/// of each column. The current version of the data in each column will not be changed.
Comment on lines +7 to +24
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML documentation formatting here doesn't match the convention used by other public enums (e.g. QueryTrackingBehavior uses indented /// ... lines and typically includes <remarks> where relevant). Please align the formatting for this public API to match the existing style.

Suggested change
/// The different ways that new objects loaded from the database can be merged with existing objects already in memory.
/// </summary>
public enum MergeOption
{
/// <summary>
/// Will only append new (top level-unique) rows. This is the default behavior.
/// </summary>
AppendOnly = 0,
/// <summary>
/// The incoming values for this row will be written to both the current value and
/// the original value versions of the data for each column.
/// </summary>
OverwriteChanges = 1,
/// <summary>
/// The incoming values for this row will be written to the original value version
/// of each column. The current version of the data in each column will not be changed.
/// The different ways that new objects loaded from the database can be merged with existing objects already in memory.
/// </summary>
public enum MergeOption
{
/// <summary>
/// Will only append new (top level-unique) rows. This is the default behavior.
/// </summary>
AppendOnly = 0,
/// <summary>
/// The incoming values for this row will be written to both the current value and
/// the original value versions of the data for each column.
/// </summary>
OverwriteChanges = 1,
/// <summary>
/// The incoming values for this row will be written to the original value version
/// of each column. The current version of the data in each column will not be changed.

Copilot uses AI. Check for mistakes.
/// </summary>
PreserveChanges = 2
}
13 changes: 13 additions & 0 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,12 @@
<data name="ReferenceMustBeLoaded" xml:space="preserve">
<value>The navigation '{1_entityType}.{0_navigation}' cannot have 'IsLoaded' set to false because the referenced entity is non-null and is therefore loaded.</value>
</data>
<data name="RefreshMultipleMergeOptions" xml:space="preserve">
<value>The Refresh method can only be called once per query. Multiple merge options were specified.</value>
</data>
<data name="RefreshNonTrackingQuery" xml:space="preserve">
<value>The Refresh method requires a tracking query. Call AsTracking() before calling Refresh(), or use a context with tracking enabled by default.</value>
</data>
<data name="RelationshipCannotBeInverted" xml:space="preserve">
<value>The principal and dependent ends of the relationship cannot be changed once foreign key or principal key properties have been specified. Remove the conflicting configuration.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ when methodCallExpression.Arguments is
_queryCompilationContext.IgnoreAutoIncludes = true;
return visitedExpression;
}

case nameof(EntityFrameworkQueryableExtensions.Refresh):
{
var visitedExpression = Visit(methodCallExpression.Arguments[0]);
_queryCompilationContext.RefreshMergeOption = methodCallExpression.Arguments[1].GetConstantValue<MergeOption>();
return visitedExpression;
}

}
}

Expand Down
15 changes: 15 additions & 0 deletions src/EFCore/Query/QueryCompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,21 @@ public QueryCompilationContext(QueryCompilationContextDependencies dependencies,
/// </summary>
public virtual bool IgnoreAutoIncludes { get; internal set; }

/// <summary>
/// <para>
/// A value indicating how already loaded objects should be merged and refreshed with the results of this query.
/// </para>
/// <para>
/// This property is typically used by database providers (and other extensions). It is generally
/// not used in application code.
/// </para>
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-providers">Implementation of database providers and extensions</see>
/// and <see href="https://aka.ms/efcore-docs-how-query-works">How EF Core queries work</see> for more information and examples.
/// </remarks>
public virtual MergeOption RefreshMergeOption { get; internal set; }

/// <summary>
/// The set of tags applied to this query.
/// </summary>
Expand Down
Loading
Loading