Skip to content
Merged
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
39 changes: 36 additions & 3 deletions src/EFCore/ChangeTracking/CollectionEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,19 @@ public override bool IsModified
}
}

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
public override void Load()
=> Load(LoadOptions.None);

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
Expand All @@ -216,7 +229,7 @@ public override bool IsModified
/// </para>
/// </remarks>
/// <param name="options">Options to control the way related entities are loaded.</param>
public override void Load(LoadOptions options = LoadOptions.None)
public override void Load(LoadOptions options)
{
EnsureInitialized();

Expand All @@ -226,6 +239,26 @@ public override void Load(LoadOptions options = LoadOptions.None)
}
}

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// Multiple active operations on the same context instance are not supported. Use <see langword="await" /> to ensure
/// that any asynchronous operations have completed before calling another method on this context.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public override Task LoadAsync(CancellationToken cancellationToken = default)
=> LoadAsync(LoadOptions.None, cancellationToken);

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
Expand All @@ -244,7 +277,7 @@ public override void Load(LoadOptions options = LoadOptions.None)
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public override Task LoadAsync(LoadOptions options = LoadOptions.None, CancellationToken cancellationToken = default)
public override Task LoadAsync(LoadOptions options, CancellationToken cancellationToken = default)
{
EnsureInitialized();

Expand All @@ -254,7 +287,7 @@ public override Task LoadAsync(LoadOptions options = LoadOptions.None, Cancellat
}

/// <summary>
/// Returns the query that would be used by <see cref="Load" /> to load entities referenced by
/// Returns the query that would be used by <see cref="Load()" /> to load entities referenced by
/// this navigation property.
/// </summary>
/// <remarks>
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/ChangeTracking/CollectionEntry`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public CollectionEntry(InternalEntityEntry internalEntry, INavigationBase naviga
}

/// <summary>
/// Returns the query that would be used by <see cref="CollectionEntry.Load" /> to load entities referenced by
/// Returns the query that would be used by <see cref="CollectionEntry.Load()" /> to load entities referenced by
/// this navigation property.
/// </summary>
/// <remarks>
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/ChangeTracking/LoadOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Microsoft.EntityFrameworkCore.ChangeTracking;

/// <summary>
/// Options to control the behavior of loading related entities with <see cref="NavigationEntry.Load" />.
/// Options to control the behavior of loading related entities with <see cref="NavigationEntry.Load(LoadOptions)" />.
/// </summary>
[Flags]
public enum LoadOptions
Expand Down
43 changes: 37 additions & 6 deletions src/EFCore/ChangeTracking/NavigationEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ private static INavigationBase GetNavigation(InternalEntityEntry internalEntry,
return navigation;
}

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
public abstract void Load();

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
Expand All @@ -95,7 +107,26 @@ private static INavigationBase GetNavigation(InternalEntityEntry internalEntry,
/// </para>
/// </remarks>
/// <param name="options">Options to control the way related entities are loaded.</param>
public abstract void Load(LoadOptions options = LoadOptions.None);
public abstract void Load(LoadOptions options);

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// Multiple active operations on the same context instance are not supported. Use <see langword="await" /> to ensure
/// that any asynchronous operations have completed before calling another method on this context.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public abstract Task LoadAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
Expand All @@ -115,10 +146,10 @@ private static INavigationBase GetNavigation(InternalEntityEntry internalEntry,
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public abstract Task LoadAsync(LoadOptions options = LoadOptions.None, CancellationToken cancellationToken = default);
public abstract Task LoadAsync(LoadOptions options, CancellationToken cancellationToken = default);

/// <summary>
/// Returns the query that would be used by <see cref="Load" /> to load entities referenced by
/// Returns the query that would be used by <see cref="Load()" /> to load entities referenced by
/// this navigation property.
/// </summary>
/// <remarks>
Expand All @@ -144,13 +175,13 @@ private static INavigationBase GetNavigation(InternalEntityEntry internalEntry,
/// <see cref="EntityFrameworkQueryableExtensions.Include{TEntity,TProperty}" /> or
/// <see
/// cref="EntityFrameworkQueryableExtensions.ThenInclude{TEntity,TPreviousProperty,TProperty}(Microsoft.EntityFrameworkCore.Query.IIncludableQueryable{TEntity,System.Collections.Generic.IEnumerable{TPreviousProperty}},System.Linq.Expressions.Expression{System.Func{TPreviousProperty,TProperty}})" />
/// , <see cref="Load" />, or <see cref="LoadAsync" /> will set this flag. Subsequent calls to <see cref="Load" />
/// or <see cref="LoadAsync" /> will then be a no-op.
/// , <see cref="Load()" />, or <see cref="LoadAsync(CancellationToken)" /> will set this flag. Subsequent calls to <see cref="Load()" />
/// or <see cref="LoadAsync(CancellationToken)" /> will then be a no-op.
/// </para>
/// <para>
/// It is possible for IsLoaded to be false even if all related entities are loaded. This is because, depending on
/// how entities are loaded, it is not always possible to know for sure that all entities in a related collection
/// have been loaded. In such cases, calling <see cref="Load" /> or <see cref="LoadAsync" /> will ensure all
/// have been loaded. In such cases, calling <see cref="Load()" /> or <see cref="LoadAsync(CancellationToken)" /> will ensure all
/// related entities are loaded and will set this flag to <see langword="true"/>.
/// </para>
/// <para>
Expand Down
39 changes: 36 additions & 3 deletions src/EFCore/ChangeTracking/ReferenceEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ private void LocalDetectChanges()
}
}

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
public override void Load()
=> Load(LoadOptions.None);

/// <summary>
/// Loads the entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
Expand All @@ -85,14 +98,34 @@ private void LocalDetectChanges()
/// </para>
/// </remarks>
/// <param name="options">Options to control the way related entities are loaded.</param>
public override void Load(LoadOptions options = LoadOptions.None)
public override void Load(LoadOptions options)
{
if (!IsLoaded)
{
TargetFinder.Load((INavigation)Metadata, InternalEntry, options);
}
}

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
/// </summary>
/// <remarks>
/// <para>
/// Multiple active operations on the same context instance are not supported. Use <see langword="await" /> to ensure
/// that any asynchronous operations have completed before calling another method on this context.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-entity-entries">Accessing tracked entities in EF Core</see>
/// and <see href="https://aka.ms/efcore-docs-load-related-data">Loading related entities</see> for more information and examples.
/// </para>
/// </remarks>
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public override Task LoadAsync(CancellationToken cancellationToken = default)
=> LoadAsync(LoadOptions.None, cancellationToken);

/// <summary>
/// Loads entities referenced by this navigation property, unless <see cref="NavigationEntry.IsLoaded" />
/// is already set to <see langword="true"/>.
Expand All @@ -111,13 +144,13 @@ public override void Load(LoadOptions options = LoadOptions.None)
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
/// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception>
public override Task LoadAsync(LoadOptions options = LoadOptions.None, CancellationToken cancellationToken = default)
public override Task LoadAsync(LoadOptions options, CancellationToken cancellationToken = default)
=> IsLoaded
? Task.CompletedTask
: TargetFinder.LoadAsync((INavigation)Metadata, InternalEntry, options, cancellationToken);

/// <summary>
/// Returns the query that would be used by <see cref="Load" /> to load entities referenced by
/// Returns the query that would be used by <see cref="Load()" /> to load entities referenced by
/// this navigation property.
/// </summary>
/// <remarks>
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/ChangeTracking/ReferenceEntry`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public ReferenceEntry(InternalEntityEntry internalEntry, INavigation navigation)
}

/// <summary>
/// Returns the query that would be used by <see cref="NavigationEntry.Load" /> to load the entity referenced by
/// Returns the query that would be used by <see cref="NavigationEntry.Load()" /> to load the entity referenced by
/// this navigation property.
/// </summary>
/// <remarks>
Expand Down