Skip to content

Commit 24dcbb7

Browse files
authored
Merge pull request #87 from Flamage82/project-method-groups
Add support for projecting method groups
2 parents 4ddf9f8 + 0deb5ce commit 24dcbb7

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

src/EntityFrameworkCore.Projectables/Services/ProjectableExpressionReplacer.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ bool TryGetReflectedExpression(MemberInfo memberInfo, [NotNullWhen(true)] out La
4141

4242
protected override Expression VisitMethodCall(MethodCallExpression node)
4343
{
44+
// Replace MethodGroup arguments with their reflected expressions.
45+
// Note that MethodCallExpression.Update returns the original Expression if argument values have not changed.
46+
node = node.Update(node.Object, node.Arguments.Select(arg => arg switch {
47+
UnaryExpression {
48+
NodeType: ExpressionType.Convert,
49+
Operand: MethodCallExpression {
50+
NodeType: ExpressionType.Call,
51+
Method: { Name: nameof(MethodInfo.CreateDelegate), DeclaringType.Name: nameof(MethodInfo) },
52+
Object: ConstantExpression { Value: MethodInfo methodInfo }
53+
}
54+
} => TryGetReflectedExpression(methodInfo, out var expressionArg) ? expressionArg : arg,
55+
_ => arg
56+
}));
57+
4458
// Get the overriding methodInfo based on te type of the received of this expression
4559
var methodInfo = node.Object?.Type.GetConcreteMethod(node.Method) ?? node.Method;
4660

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SELECT [e].[Id], [e0].[Id] + 1, [e0].[Id]
2+
FROM [Entity] AS [e]
3+
LEFT JOIN [Entity] AS [e0] ON [e].[Id] = [e0].[EntityId]
4+
ORDER BY [e].[Id]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using EntityFrameworkCore.Projectables.FunctionalTests.Helpers;
5+
using Microsoft.EntityFrameworkCore;
6+
using VerifyXunit;
7+
using Xunit;
8+
9+
namespace EntityFrameworkCore.Projectables.FunctionalTests;
10+
11+
[UsesVerify]
12+
public class MethodGroupTests
13+
{
14+
public record Entity
15+
{
16+
public int Id { get; set; }
17+
18+
public List<Entity>? RelatedEntities { get; set; }
19+
}
20+
21+
[Projectable]
22+
public static int NextId(Entity entity) => entity.Id + 1;
23+
24+
[Fact]
25+
public Task ProjectOverMethodGroup()
26+
{
27+
using var dbContext = new SampleDbContext<Entity>();
28+
29+
var query = dbContext.Set<Entity>()
30+
.Select(x => new { NextIds = x.RelatedEntities!.Select(NextId) });
31+
32+
return Verifier.Verify(query.ToQueryString());
33+
}
34+
}

0 commit comments

Comments
 (0)