Skip to content

Commit

Permalink
Fix #6248 - Rework the way QueryProvider is obtained as the previous …
Browse files Browse the repository at this point in the history
…approach broke query caching.
  • Loading branch information
anpete committed Aug 4, 2016
1 parent 4df411a commit b6d7673
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,31 @@ public virtual async Task ToListAsync_can_be_canceled()
}
}

//[ConditionalFact] // TODO: #6248
// public virtual async Task Mixed_sync_async_query()
// {
// using (var context = CreateContext())
// {
// var results
// = (await context.Customers
// .Select(c => new
// {
// c.CustomerID,
// Orders = context.Orders.Where(o => o.Customer.CustomerID == c.CustomerID)
// }).ToListAsync())
// .Select(x => new
// {
// Orders = x.Orders
// .GroupJoin(new[] { "ALFKI" }, y => x.CustomerID, y => y, (h, id) => new
// {
// h.Customer
// })
// })
// .ToList();
//
// Assert.Equal(546, results.SelectMany(r => r.Orders).ToList().Count);
// }
// }
[ConditionalFact]
public virtual async Task Mixed_sync_async_query()
{
using (var context = CreateContext())
{
var results
= (await context.Customers
.Select(c => new
{
c.CustomerID,
Orders = context.Orders.Where(o => o.Customer.CustomerID == c.CustomerID)
}).ToListAsync())
.Select(x => new
{
Orders = x.Orders
.GroupJoin(new[] { "ALFKI" }, y => x.CustomerID, y => y, (h, id) => new
{
h.Customer
})
})
.ToList();

Assert.Equal(546, results.SelectMany(r => r.Orders).ToList().Count);
}
}

[ConditionalFact]
public virtual async Task LoadAsync_should_track_results()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,6 @@ public virtual ParameterExpression CurrentParameter
/// </summary>
public virtual ILinqOperatorProvider LinqOperatorProvider { get; private set; }

/// <summary>
/// Gets the <see cref="IQueryProvider"/> being used for this query.
/// </summary>
public virtual IQueryProvider QueryProvider { get; [param: NotNull] set; }

/// <summary>
/// Creates an action to execute this query.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,10 @@ protected EntityQueryableExpressionVisitor([NotNull] EntityQueryModelVisitor ent
/// <param name="constantExpression"> The node being visited. </param>
/// <returns> An expression to use in place of the node. </returns>
protected override Expression VisitConstant(ConstantExpression constantExpression)
{
if (constantExpression.Type.GetTypeInfo().IsGenericType
&& constantExpression.Type.GetGenericTypeDefinition() == typeof(EntityQueryable<>))
{
var queryable = (IQueryable)constantExpression.Value;

QueryModelVisitor.QueryProvider = queryable.Provider;

return VisitEntityQueryable(queryable.ElementType);
}

return constantExpression;
}
=> constantExpression.Type.GetTypeInfo().IsGenericType
&& constantExpression.Type.GetGenericTypeDefinition() == typeof(EntityQueryable<>)
? VisitEntityQueryable(((IQueryable)constantExpression.Value).ElementType)
: constantExpression;

/// <summary>
/// Visits entity type roots.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected override Expression VisitSubQuery(SubQueryExpression expression)
QueryModelVisitor.LinqOperatorProvider.ToQueryable
.MakeGenericMethod(expression.Type.GetSequenceType()),
subExpression,
Expression.Constant(QueryModelVisitor.QueryProvider));
EntityQueryModelVisitor.QueryContextParameter);
}
else if (subQueryExpressionTypeInfo.IsGenericType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,18 +321,20 @@ private static readonly MethodInfo _toQueryable
[UsedImplicitly]
// ReSharper disable once InconsistentNaming
private static IOrderedQueryable<TSource> _ToQueryable<TSource>(
IAsyncEnumerable<TSource> source, IAsyncQueryProvider queryProvider)
=> new AsyncQueryableAdapter<TSource>(source, queryProvider);
IAsyncEnumerable<TSource> source, QueryContext queryContext)
=> new AsyncQueryableAdapter<TSource>(source, queryContext);

private sealed class AsyncQueryableAdapter<T> : IOrderedQueryable<T>
{
private readonly IAsyncEnumerable<T> _source;
private readonly QueryContext _queryContext;
private readonly ConstantExpression _constantExpression;

public AsyncQueryableAdapter(IAsyncEnumerable<T> source, IQueryProvider queryProvider)
public AsyncQueryableAdapter(IAsyncEnumerable<T> source, QueryContext queryContext)
{
_source = source;
Provider = queryProvider;
_queryContext = queryContext;

_constantExpression = Expression.Constant(this);
}

Expand All @@ -344,7 +346,7 @@ public AsyncQueryableAdapter(IAsyncEnumerable<T> source, IQueryProvider queryPro

public Expression Expression => _constantExpression;

public IQueryProvider Provider { get; }
public IQueryProvider Provider => _queryContext.QueryProvider;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,18 +299,20 @@ private static readonly MethodInfo _toQueryable
[UsedImplicitly]
// ReSharper disable once InconsistentNaming
private static IOrderedQueryable<TSource> _ToQueryable<TSource>(
IEnumerable<TSource> source, IQueryProvider queryProvider)
=> new QueryableAdapter<TSource>(source, queryProvider);
IEnumerable<TSource> source, QueryContext queryContext)
=> new QueryableAdapter<TSource>(source, queryContext);

private sealed class QueryableAdapter<T> : IOrderedQueryable<T>
{
private readonly IEnumerable<T> _source;
private readonly QueryContext _queryContext;
private readonly ConstantExpression _constantExpression;

public QueryableAdapter(IEnumerable<T> source, IQueryProvider queryProvider)
public QueryableAdapter(IEnumerable<T> source, QueryContext queryContext)
{
_source = source;
Provider = queryProvider;
_queryContext = queryContext;

_constantExpression = Expression.Constant(this);
}

Expand All @@ -322,7 +324,7 @@ public QueryableAdapter(IEnumerable<T> source, IQueryProvider queryProvider)

public Expression Expression => _constantExpression;

public IQueryProvider Provider { get; }
public IQueryProvider Provider => _queryContext.QueryProvider;
}

/// <summary>
Expand Down
9 changes: 9 additions & 0 deletions src/Microsoft.EntityFrameworkCore/Query/QueryContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
Expand Down Expand Up @@ -57,6 +58,14 @@ public virtual IQueryBuffer QueryBuffer
/// </value>
public virtual LazyRef<IStateManager> StateManager { get; }

/// <summary>
/// The query provider.
/// </summary>
/// <value>
/// The query provider.
/// </value>
public virtual IQueryProvider QueryProvider => StateManager.Value.Context.QueryProvider;

/// <summary>
/// Gets the concurrency detector.
/// </summary>
Expand Down

0 comments on commit b6d7673

Please sign in to comment.