diff --git a/src/EntityFrameworkCore.Projectables/Services/ProjectableExpressionReplacer.cs b/src/EntityFrameworkCore.Projectables/Services/ProjectableExpressionReplacer.cs index 8cfb703..6b478f9 100644 --- a/src/EntityFrameworkCore.Projectables/Services/ProjectableExpressionReplacer.cs +++ b/src/EntityFrameworkCore.Projectables/Services/ProjectableExpressionReplacer.cs @@ -41,6 +41,20 @@ bool TryGetReflectedExpression(MemberInfo memberInfo, [NotNullWhen(true)] out La protected override Expression VisitMethodCall(MethodCallExpression node) { + // Replace MethodGroup arguments with their reflected expressions. + // Note that MethodCallExpression.Update returns the original Expression if argument values have not changed. + node = node.Update(node.Object, node.Arguments.Select(arg => arg switch { + UnaryExpression { + NodeType: ExpressionType.Convert, + Operand: MethodCallExpression { + NodeType: ExpressionType.Call, + Method: { Name: nameof(MethodInfo.CreateDelegate), DeclaringType.Name: nameof(MethodInfo) }, + Object: ConstantExpression { Value: MethodInfo methodInfo } + } + } => TryGetReflectedExpression(methodInfo, out var expressionArg) ? expressionArg : arg, + _ => arg + })); + // Get the overriding methodInfo based on te type of the received of this expression var methodInfo = node.Object?.Type.GetConcreteMethod(node.Method) ?? node.Method; diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.ProjectOverMethodGroup.verified.txt b/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.ProjectOverMethodGroup.verified.txt new file mode 100644 index 0000000..94ca81e --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.ProjectOverMethodGroup.verified.txt @@ -0,0 +1,4 @@ +SELECT [e].[Id], [e0].[Id] + 1, [e0].[Id] +FROM [Entity] AS [e] +LEFT JOIN [Entity] AS [e0] ON [e].[Id] = [e0].[EntityId] +ORDER BY [e].[Id] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.cs b/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.cs new file mode 100644 index 0000000..d9e8ab4 --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/MethodGroupTests.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EntityFrameworkCore.Projectables.FunctionalTests.Helpers; +using Microsoft.EntityFrameworkCore; +using VerifyXunit; +using Xunit; + +namespace EntityFrameworkCore.Projectables.FunctionalTests; + +[UsesVerify] +public class MethodGroupTests +{ + public record Entity + { + public int Id { get; set; } + + public List? RelatedEntities { get; set; } + } + + [Projectable] + public static int NextId(Entity entity) => entity.Id + 1; + + [Fact] + public Task ProjectOverMethodGroup() + { + using var dbContext = new SampleDbContext(); + + var query = dbContext.Set() + .Select(x => new { NextIds = x.RelatedEntities!.Select(NextId) }); + + return Verifier.Verify(query.ToQueryString()); + } +} \ No newline at end of file