Skip to content

Commit 74f7799

Browse files
committed
Query : Add support for final GroupBy operator
Resolves #19929
1 parent 1117c14 commit 74f7799

File tree

33 files changed

+3597
-1077
lines changed

33 files changed

+3597
-1077
lines changed

src/EFCore.InMemory/Extensions/InMemoryServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static IServiceCollection AddEntityFrameworkInMemoryDatabase(this IServic
4848
.TryAdd<ITypeMappingSource, InMemoryTypeMappingSource>()
4949
.TryAdd<IShapedQueryCompilingExpressionVisitorFactory, InMemoryShapedQueryCompilingExpressionVisitorFactory>()
5050
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory, InMemoryQueryableMethodTranslatingExpressionVisitorFactory>()
51+
.TryAdd<IQueryTranslationPreprocessorFactory, InMemoryQueryTranslationPreprocessorFactory>()
5152
.TryAdd<ISingletonOptions, IInMemorySingletonOptions>(p => p.GetRequiredService<IInMemorySingletonOptions>())
5253
.TryAddProviderSpecificServices(
5354
b => b

src/EFCore.InMemory/Properties/InMemoryStrings.Designer.cs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/EFCore.InMemory/Properties/InMemoryStrings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@
134134
<value>Transactions are not supported by the in-memory store. See http://go.microsoft.com/fwlink/?LinkId=800142</value>
135135
<comment>Warning InMemoryEventId.TransactionIgnoredWarning</comment>
136136
</data>
137+
<data name="NoncomposedGroupByNotSupported" xml:space="preserve">
138+
<value>A 'GroupBy' operation which is not composed into aggregate or projection of elements is not supported.</value>
139+
</data>
137140
<data name="NoQueryStrings" xml:space="preserve">
138141
<value>There is no query string because the in-memory provider does not use a string-based query language.</value>
139142
</data>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.EntityFrameworkCore.InMemory.Internal;
5+
using System.Linq.Expressions;
6+
7+
namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal;
8+
9+
/// <summary>
10+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
11+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
12+
/// any release. You should only use it directly in your code with extreme caution and knowing that
13+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
14+
/// </summary>
15+
public class InMemoryQueryTranslationPreprocessor : QueryTranslationPreprocessor
16+
{
17+
/// <summary>
18+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
19+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
20+
/// any release. You should only use it directly in your code with extreme caution and knowing that
21+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
22+
/// </summary>
23+
public InMemoryQueryTranslationPreprocessor(
24+
QueryTranslationPreprocessorDependencies dependencies,
25+
QueryCompilationContext queryCompilationContext)
26+
: base(dependencies, queryCompilationContext)
27+
{
28+
}
29+
30+
/// <summary>
31+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
32+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
33+
/// any release. You should only use it directly in your code with extreme caution and knowing that
34+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
35+
/// </summary>
36+
public override Expression Process(Expression query)
37+
{
38+
var result = base.Process(query);
39+
40+
if (result is MethodCallExpression methodCallExpression
41+
&& methodCallExpression.Method.IsGenericMethod
42+
&& (methodCallExpression.Method.GetGenericMethodDefinition() == QueryableMethods.GroupByWithKeySelector
43+
|| methodCallExpression.Method.GetGenericMethodDefinition() == QueryableMethods.GroupByWithKeyElementSelector))
44+
{
45+
throw new InvalidOperationException(
46+
CoreStrings.TranslationFailedWithDetails(methodCallExpression.Print(), InMemoryStrings.NoncomposedGroupByNotSupported));
47+
}
48+
49+
return result;
50+
}
51+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal;
5+
6+
/// <summary>
7+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
8+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
9+
/// any release. You should only use it directly in your code with extreme caution and knowing that
10+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
11+
/// </summary>
12+
public class InMemoryQueryTranslationPreprocessorFactory : IQueryTranslationPreprocessorFactory
13+
{
14+
/// <summary>
15+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
16+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
17+
/// any release. You should only use it directly in your code with extreme caution and knowing that
18+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
19+
/// </summary>
20+
public InMemoryQueryTranslationPreprocessorFactory(
21+
QueryTranslationPreprocessorDependencies dependencies)
22+
{
23+
Dependencies = dependencies;
24+
}
25+
26+
/// <summary>
27+
/// Dependencies for this service.
28+
/// </summary>
29+
protected virtual QueryTranslationPreprocessorDependencies Dependencies { get; }
30+
31+
/// <summary>
32+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
33+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
34+
/// any release. You should only use it directly in your code with extreme caution and knowing that
35+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
36+
/// </summary>
37+
public virtual QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext)
38+
=> new InMemoryQueryTranslationPreprocessor(Dependencies, queryCompilationContext);
39+
}

src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.EntityFrameworkCore.InMemory.Internal;
5+
46
namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal;
57

68
/// <summary>

0 commit comments

Comments
 (0)