Skip to content

Commit

Permalink
Query: Add IgnoreEagerLoadedNavigations API
Browse files Browse the repository at this point in the history
Part of #2953
  • Loading branch information
smitpatel committed Dec 18, 2019
1 parent b25d0b1 commit 2ded191
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
33 changes: 33 additions & 0 deletions src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs
Expand Up @@ -2384,6 +2384,39 @@ public IAsyncEnumerator<TEntity> GetAsyncEnumerator(CancellationToken cancellati

#endregion

#region Eager loaded navigations

internal static readonly MethodInfo IgnoreEagerLoadedNavigationsMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
.GetTypeInfo().GetDeclaredMethod(nameof(IgnoreEagerLoadedNavigations));

/// <summary>
/// Specifies that the current Entity Framework LINQ query should not have any
/// model-level eager loaded navigations applied.
/// </summary>
/// <typeparam name="TEntity"> The type of entity being queried. </typeparam>
/// <param name="source"> The source query. </param>
/// <returns>
/// A new query that will not apply any model-level eager loaded navigations.
/// </returns>
public static IQueryable<TEntity> IgnoreEagerLoadedNavigations<TEntity>(
[NotNull] this IQueryable<TEntity> source)
where TEntity : class
{
Check.NotNull(source, nameof(source));

return
source.Provider is EntityQueryProvider
? source.Provider.CreateQuery<TEntity>(
Expression.Call(
instance: null,
method: IgnoreEagerLoadedNavigationsMethodInfo.MakeGenericMethod(typeof(TEntity)),
arguments: source.Expression))
: source;
}

#endregion

#region Query Filters

internal static readonly MethodInfo IgnoreQueryFiltersMethodInfo
Expand Down
Expand Up @@ -1443,9 +1443,17 @@ private string GetParameterName(string prefix)
return uniqueName;
}

private static void PopulateEagerLoadedNavigations(IncludeTreeNode includeTreeNode)
private void PopulateEagerLoadedNavigations(IncludeTreeNode includeTreeNode)
{
var entityType = includeTreeNode.EntityType;

if (_queryCompilationContext.IgnoreEagerLoadedNavigations
&& !entityType.IsOwned()
&& !entityType.HasDefiningNavigation())
{
return;
}

var outboundNavigations
= entityType.GetNavigations()
.Concat(entityType.GetDerivedNavigations())
Expand Down
Expand Up @@ -46,11 +46,16 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp

if (genericMethodDefinition == EntityFrameworkQueryableExtensions.IgnoreQueryFiltersMethodInfo)
{
var innerQueryable = Visit(methodCallExpression.Arguments[0]);

_queryCompilationContext.IgnoreQueryFilters = true;

return innerQueryable;
return Visit(methodCallExpression.Arguments[0]);
}

if (genericMethodDefinition == EntityFrameworkQueryableExtensions.IgnoreEagerLoadedNavigationsMethodInfo)
{
_queryCompilationContext.IgnoreEagerLoadedNavigations = true;

return Visit(methodCallExpression.Arguments[0]);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/EFCore/Query/QueryCompilationContext.cs
Expand Up @@ -56,6 +56,7 @@ public class QueryCompilationContext
public virtual bool IsTracking { get; internal set; }
public virtual bool IsBuffering { get; }
public virtual bool IgnoreQueryFilters { get; internal set; }
public virtual bool IgnoreEagerLoadedNavigations { get; internal set; }
public virtual ISet<string> Tags { get; } = new HashSet<string>();
public virtual IDiagnosticsLogger<DbLoggerCategory.Query> Logger { get; }
public virtual Type ContextType { get; }
Expand Down

0 comments on commit 2ded191

Please sign in to comment.