Skip to content

Commit

Permalink
Query: Allow creating query roots without provider
Browse files Browse the repository at this point in the history
When entity queryables are injected while compiling a query, they don't need query provider
External queries only need query provider to make sure that we are using DbSets from same context
  • Loading branch information
smitpatel committed Mar 3, 2020
1 parent e210931 commit ee82100
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

Expand Down Expand Up @@ -87,7 +88,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
&& memberExpression.Type.GetGenericTypeDefinition() == typeof(DbSet<>)
&& _model != null)
{
return NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(FindEntityType(memberExpression.Type));
return new QueryRootExpression(FindEntityType(memberExpression.Type));
}

return base.VisitMember(memberExpression);
Expand All @@ -104,7 +105,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
&& methodCallExpression.Type.GetGenericTypeDefinition() == typeof(DbSet<>)
&& _model != null)
{
return NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(FindEntityType(methodCallExpression.Type));
return new QueryRootExpression(FindEntityType(methodCallExpression.Type));
}

return base.VisitMethodCall(methodCallExpression);
Expand Down
33 changes: 0 additions & 33 deletions src/EFCore/Query/Internal/AsyncQueryProviderExtensions.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ protected Expression ExpandNavigation(
return ownedExpansion;
}

var innerQueryable = NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(targetType);
var innerQueryable = new QueryRootExpression(targetType);
var innerSource = (NavigationExpansionExpression)_navigationExpandingExpressionVisitor.Visit(innerQueryable);
if (entityReference.IncludePaths.ContainsKey(navigation))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ private Expression ApplyQueryFilter(NavigationExpansionExpression navigationExpa
// entity information through. Construct a MethodCall wrapper for the predicate with the proper query root.
var filterWrapper = Expression.Call(
QueryableMethods.Where.MakeGenericMethod(rootEntityType.ClrType),
NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(rootEntityType),
new QueryRootExpression(rootEntityType),
filterPredicate);
var rewrittenFilterWrapper = (MethodCallExpression)_entityEqualityRewritingExpressionVisitor.Rewrite(filterWrapper);
filterPredicate = rewrittenFilterWrapper.Arguments[1].UnwrapLambdaFromQuote();
Expand Down
12 changes: 10 additions & 2 deletions src/EFCore/Query/QueryRootExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Query
Expand All @@ -26,10 +25,19 @@ public QueryRootExpression([NotNull] IAsyncQueryProvider asyncQueryProvider, [No
_type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType);
}

public QueryRootExpression([NotNull] IEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));

EntityType = entityType;
QueryProvider = null;
_type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType);
}

public virtual IAsyncQueryProvider QueryProvider { get; }
public virtual IEntityType EntityType { get; }

public virtual Expression DetachQueryProvider() => new QueryRootExpression(NullAsyncQueryProvider.Instance, EntityType);
public virtual Expression DetachQueryProvider() => new QueryRootExpression(EntityType);
public override ExpressionType NodeType => ExpressionType.Extension;
public override Type Type => _type;
public override bool CanReduce => false;
Expand Down

0 comments on commit ee82100

Please sign in to comment.