Skip to content

Commit a8bc2b6

Browse files
committed
Query: Add CompileQuery overloads taking upto 15 parameters
Resolves #20606 Upto 15 parameters are allowed. We cannot go further than that. Our return type is Func<> which does not allow more than 16 in parameters. One fixed parameter is TContext. Due to same limitation, the CompileAsyncQuery which also takes cancellationToken can support only upto 14 other parameters.
1 parent de92ba0 commit a8bc2b6

14 files changed

+2921
-200
lines changed

src/EFCore/EF.CompileAsyncQuery.cs

Lines changed: 1060 additions & 46 deletions
Large diffs are not rendered by default.

src/EFCore/EF.CompileAsyncQuery.tt

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<#@ assembly name="System.Core" #>
2+
<#@ import namespace="System.Collections.Generic" #>
3+
<#@ import namespace="System.Linq" #>
4+
// Copyright (c) .NET Foundation. All rights reserved.
5+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
6+
// <auto-generated />
7+
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Linq;
11+
using System.Linq.Expressions;
12+
using System.Threading;
13+
using System.Threading.Tasks;
14+
using JetBrains.Annotations;
15+
using Microsoft.EntityFrameworkCore.Query;
16+
using Microsoft.EntityFrameworkCore.Query.Internal;
17+
18+
namespace Microsoft.EntityFrameworkCore
19+
{
20+
public static partial class EF
21+
{
22+
/// <summary>
23+
/// Creates a compiled query delegate that when invoked will execute the specified LINQ query.
24+
/// </summary>
25+
/// <typeparam name="TContext">The target DbContext type.</typeparam>
26+
/// <typeparam name="TResult">The query result type.</typeparam>
27+
/// <param name="queryExpression">The LINQ query expression.</param>
28+
/// <returns>A delegate that can be invoked to execute the compiled query.</returns>
29+
public static Func<TContext, IAsyncEnumerable<TResult>> CompileAsyncQuery<TContext, TResult>(
30+
[NotNull] Expression<Func<TContext, DbSet<TResult>>> queryExpression)
31+
where TContext : DbContext
32+
where TResult : class
33+
=> new CompiledAsyncEnumerableQuery<TContext, TResult>(queryExpression).Execute;
34+
<#
35+
var ordinal = new[] { "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth" };
36+
37+
var maxParameters = 15;
38+
39+
for (var parameterCount = 0; parameterCount <= maxParameters; parameterCount++)
40+
{
41+
var paramsList = string.Join("", Enumerable.Range(1, parameterCount).Select(e => "TParam" + e + ", "));
42+
#>
43+
44+
/// <summary>
45+
/// Creates a compiled query delegate that when invoked will execute the specified LINQ query.
46+
/// </summary>
47+
/// <typeparam name="TContext">The target DbContext type.</typeparam>
48+
<# for (var i = 1; i <= parameterCount; i++) { #>
49+
/// <typeparam name="TParam<#= i #>">The type of the <#= ordinal[i - 1] #> query parameter.</typeparam>
50+
<# } #>
51+
/// <typeparam name="TResult">The query result type.</typeparam>
52+
/// <typeparam name="TProperty">The included property type.</typeparam>
53+
/// <param name="queryExpression">The LINQ query expression.</param>
54+
/// <returns>A delegate that can be invoked to execute the compiled query.</returns>
55+
<# if (parameterCount <= 2 ) { #>
56+
public static Func<TContext, <#= paramsList #>IAsyncEnumerable<TResult>> CompileAsyncQuery<TContext, <#= paramsList #>TResult, TProperty>(
57+
<# } else { #>
58+
public static Func<TContext, <#= paramsList #>IAsyncEnumerable<TResult>> CompileAsyncQuery<
59+
TContext, <#= paramsList #>TResult, TProperty>(
60+
<# } #>
61+
[NotNull] Expression<Func<TContext, <#= paramsList #>IIncludableQueryable<TResult, TProperty>>> queryExpression)
62+
where TContext : DbContext
63+
=> new CompiledAsyncEnumerableQuery<TContext, TResult>(queryExpression).Execute;
64+
65+
/// <summary>
66+
/// Creates a compiled query delegate that when invoked will execute the specified LINQ query.
67+
/// </summary>
68+
/// <typeparam name="TContext">The target DbContext type.</typeparam>
69+
<# for (var i = 1; i <= parameterCount; i++) { #>
70+
/// <typeparam name="TParam<#= i #>">The type of the <#= ordinal[i - 1] #> query parameter.</typeparam>
71+
<# } #>
72+
/// <typeparam name="TResult">The query result type.</typeparam>
73+
/// <param name="queryExpression">The LINQ query expression.</param>
74+
/// <returns>A delegate that can be invoked to execute the compiled query.</returns>
75+
<# if (parameterCount <= 2 ) { #>
76+
public static Func<TContext, <#= paramsList #>IAsyncEnumerable<TResult>> CompileAsyncQuery<TContext, <#= paramsList #>TResult>(
77+
<# } else { #>
78+
public static Func<TContext, <#= paramsList #>IAsyncEnumerable<TResult>> CompileAsyncQuery<
79+
TContext, <#= paramsList #>TResult>(
80+
<# } #>
81+
[NotNull] Expression<Func<TContext, <#= paramsList #>IQueryable<TResult>>> queryExpression)
82+
where TContext : DbContext
83+
=> new CompiledAsyncEnumerableQuery<TContext, TResult>(queryExpression).Execute;
84+
85+
/// <summary>
86+
/// Creates a compiled query delegate that when invoked will execute the specified LINQ query.
87+
/// </summary>
88+
/// <typeparam name="TContext">The target DbContext type.</typeparam>
89+
<# for (var i = 1; i <= parameterCount; i++) { #>
90+
/// <typeparam name="TParam<#= i #>">The type of the <#= ordinal[i - 1] #> query parameter.</typeparam>
91+
<# } #>
92+
/// <typeparam name="TResult">The query result type.</typeparam>
93+
/// <param name="queryExpression">The LINQ query expression.</param>
94+
/// <returns>A delegate that can be invoked to execute the compiled query.</returns>
95+
<# if (parameterCount <= 3 ) { #>
96+
public static Func<TContext, <#= paramsList #>Task<TResult>> CompileAsyncQuery<TContext, <#= paramsList #>TResult>(
97+
<# } else { #>
98+
public static Func<TContext, <#= paramsList #>Task<TResult>> CompileAsyncQuery<
99+
TContext, <#= paramsList #>TResult>(
100+
<# } #>
101+
[NotNull] Expression<Func<TContext, <#= paramsList #>TResult>> queryExpression)
102+
where TContext : DbContext
103+
=> new CompiledAsyncTaskQuery<TContext, TResult>(queryExpression).ExecuteAsync;
104+
<# if (parameterCount < 15) { #>
105+
106+
/// <summary>
107+
/// Creates a compiled query delegate that when invoked will execute the specified LINQ query.
108+
/// </summary>
109+
/// <typeparam name="TContext">The target DbContext type.</typeparam>
110+
<# for (var i = 1; i <= parameterCount; i++) { #>
111+
/// <typeparam name="TParam<#= i #>">The type of the <#= ordinal[i - 1] #> query parameter.</typeparam>
112+
<# } #>
113+
/// <typeparam name="TResult">The query result type.</typeparam>
114+
/// <param name="queryExpression">The LINQ query expression.</param>
115+
/// <returns>A delegate that can be invoked to execute the compiled query.</returns>
116+
<# if (parameterCount <= 3 ) { #>
117+
public static Func<TContext, <#= paramsList #>CancellationToken, Task<TResult>> CompileAsyncQuery<TContext, <#= paramsList #>TResult>(
118+
<# } else { #>
119+
public static Func<TContext, <#= paramsList #>CancellationToken, Task<TResult>> CompileAsyncQuery<
120+
TContext, <#= paramsList #>TResult>(
121+
<# } #>
122+
[NotNull] Expression<Func<TContext, <#= paramsList #>CancellationToken, TResult>> queryExpression)
123+
where TContext : DbContext
124+
=> new CompiledAsyncTaskQuery<TContext, TResult>(queryExpression).ExecuteAsync;
125+
<# } #>
126+
<#
127+
}
128+
#>
129+
}
130+
}

0 commit comments

Comments
 (0)