Skip to content

Commit

Permalink
Query: Self-bootstrapping functions returning IQueryable (#21487)
Browse files Browse the repository at this point in the history
Public method FromExpression on DbContext to tie up our query provider with the expression

Resolves #9810
  • Loading branch information
smitpatel committed Jul 2, 2020
1 parent 928e87b commit e327d2c
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 12 deletions.
11 changes: 4 additions & 7 deletions src/EFCore/DbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,16 +1707,13 @@ public virtual ValueTask<TEntity> FindAsync<TEntity>([CanBeNull] object[] keyVal
IServiceProvider IInfrastructure<IServiceProvider>.Instance => InternalServiceProvider;

/// <summary>
/// Creates a query expression, which represents a function call, against the query store.
/// Creates a queryable for given query expression.
/// </summary>
/// <typeparam name="TResult"> The result type of the query expression </typeparam>
/// <typeparam name="TResult"> The result type of the query expression. </typeparam>
/// <param name="expression"> The query expression to create. </param>
/// <returns> An IQueryable representing the query. </returns>
protected virtual IQueryable<TResult> CreateQuery<TResult>([NotNull] Expression<Func<IQueryable<TResult>>> expression)
/// <returns> An <see cref="IQueryable{T}"/> representing the query. </returns>
public virtual IQueryable<TResult> FromExpression<TResult>([NotNull] Expression<Func<IQueryable<TResult>>> expression)
{
//should we add this method as an extension in relational? That would require making DbContextDependencies public.
//Is there a 3rd way?

Check.NotNull(expression, nameof(expression));

return DbContextDependencies.QueryProvider.CreateQuery<TResult>(expression.Body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public class MultProductOrders

public IQueryable<OrderByYear> GetCustomerOrderCountByYear(int customerId)
{
return CreateQuery(() => GetCustomerOrderCountByYear(customerId));
return FromExpression(() => GetCustomerOrderCountByYear(customerId));
}

public class TopSellingProduct
Expand All @@ -184,17 +184,17 @@ public class TopSellingProduct

public IQueryable<TopSellingProduct> GetTopTwoSellingProducts()
{
return CreateQuery(() => GetTopTwoSellingProducts());
return FromExpression(() => GetTopTwoSellingProducts());
}

public IQueryable<TopSellingProduct> GetTopSellingProductsForCustomer(int customerId)
{
return CreateQuery(() => GetTopSellingProductsForCustomer(customerId));
return FromExpression(() => GetTopSellingProductsForCustomer(customerId));
}

public IQueryable<MultProductOrders> GetOrdersWithMultipleProducts(int customerId)
{
return CreateQuery(() => GetOrdersWithMultipleProducts(customerId));
return FromExpression(() => GetOrdersWithMultipleProducts(customerId));
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion test/EFCore.Tests/DbContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ public async Task It_throws_object_disposed_exception(bool async)
await Assert.ThrowsAsync<ObjectDisposedException>(() => context.FindAsync(typeof(Random), 77).AsTask());

var methodCount = typeof(DbContext).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Count();
var expectedMethodCount = 42 + 1;
var expectedMethodCount = 42 + 2;
Assert.True(
methodCount == expectedMethodCount,
userMessage: $"Expected {expectedMethodCount} methods on DbContext but found {methodCount}. "
Expand Down

0 comments on commit e327d2c

Please sign in to comment.