diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/Entity.cs b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/Entity.cs index 4edc475..8201933 100644 --- a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/Entity.cs +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/Entity.cs @@ -5,6 +5,6 @@ public class Entity { public int Id { get; set; } public string Name { get; set; } = string.Empty; - } + } } #endif diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/EntityExtensions.cs b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/EntityExtensions.cs index f0c8c21..63b36d4 100644 --- a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/EntityExtensions.cs +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/EntityExtensions.cs @@ -23,6 +23,15 @@ public static class EntityExtensions [Projectable] public int Multiply(int factor) => e.Id * factor; } + + extension (GenericWrapper w) + { + /// + /// Extension member method that multiplies the wrapped entity's ID by a factor. + /// + [Projectable] + public int MultiplyWrapped(int factor) => w.Wrapped.Id * factor; + } } public static class IntExtensions diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.ExtensionMemberMethodWithParameterOnWrappedEntity.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.ExtensionMemberMethodWithParameterOnWrappedEntity.DotNet10_0.verified.txt new file mode 100644 index 0000000..fda5a32 --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.ExtensionMemberMethodWithParameterOnWrappedEntity.DotNet10_0.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] * 10 +FROM [Entity] AS [e] diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.cs b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.cs index cf776d1..f5ea5b9 100644 --- a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.cs +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/ExtensionMemberTests.cs @@ -37,6 +37,18 @@ public Task ExtensionMemberMethodWithParameterOnEntity() return Verifier.Verify(query.ToQueryString()); } + + [Fact] + public Task ExtensionMemberMethodWithParameterOnWrappedEntity() + { + using var dbContext = new SampleDbContext(); + + var query = dbContext.Set() + .Select(x => new GenericWrapper { Wrapped = x }) + .Select(w => w.MultiplyWrapped(10)); + + return Verifier.Verify(query.ToQueryString()); + } } } #endif diff --git a/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/GenericWrapper.cs b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/GenericWrapper.cs new file mode 100644 index 0000000..d503523 --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.FunctionalTests/ExtensionMembers/GenericWrapper.cs @@ -0,0 +1,9 @@ +#if NET10_0_OR_GREATER +namespace EntityFrameworkCore.Projectables.FunctionalTests.ExtensionMembers +{ + public sealed class GenericWrapper + { + public required T Wrapped { get; set; } + } +} +#endif diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnGenericType.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnGenericType.verified.txt new file mode 100644 index 0000000..2a014de --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnGenericType.verified.txt @@ -0,0 +1,17 @@ +// +#nullable disable +using System; +using EntityFrameworkCore.Projectables; +using Foo; + +namespace EntityFrameworkCore.Projectables.Generated +{ + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + static class Foo_EntityExtensions_TimesHundred + { + static global::System.Linq.Expressions.Expression, int>> Expression() + { + return (global::Foo.Wrapper @this) => @this.Wrapped.Value * 100; + } + } +} diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs index f5bdbae..dd2d7f9 100644 --- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs +++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs @@ -17,10 +17,10 @@ public Task ExtensionMemberProperty() using EntityFrameworkCore.Projectables; namespace Foo { - class Entity { + class Entity { public int Id { get; set; } } - + static class EntityExtensions { extension(Entity e) { [Projectable] @@ -46,10 +46,10 @@ public Task ExtensionMemberMethod() using EntityFrameworkCore.Projectables; namespace Foo { - class Entity { + class Entity { public int Id { get; set; } } - + static class EntityExtensions { extension(Entity e) { [Projectable] @@ -75,10 +75,10 @@ public Task ExtensionMemberMethodWithParameters() using EntityFrameworkCore.Projectables; namespace Foo { - class Entity { + class Entity { public int Id { get; set; } } - + static class EntityExtensions { extension(Entity e) { [Projectable] @@ -127,11 +127,11 @@ public Task ExtensionMemberWithMemberAccess() using EntityFrameworkCore.Projectables; namespace Foo { - class Entity { + class Entity { public int Id { get; set; } public string Name { get; set; } } - + static class EntityExtensions { extension(Entity e) { [Projectable] @@ -277,7 +277,39 @@ static class EntityExtensions { Assert.Empty(result.Diagnostics); Assert.Single(result.GeneratedTrees); + return Verifier.Verify(result.GeneratedTrees[0].ToString()); + } + [Fact] + public Task ExtensionMemberOnGenericType() + { + var compilation = CreateCompilation(@" +using System; +using EntityFrameworkCore.Projectables; + +namespace Foo { + class Entity { + public int Value { get; set; } + } + + class Wrapper { + public T Wrapped { get; set; } + } + + static class EntityExtensions { + extension(Wrapper e) { + [Projectable] + public int TimesHundred => e.Wrapped.Value * 100; + } + } +} +"); + + var result = RunGenerator(compilation); + + Assert.Empty(result.Diagnostics); + Assert.Single(result.GeneratedTrees); + return Verifier.Verify(result.GeneratedTrees[0].ToString()); } #endif -} \ No newline at end of file +}