Skip to content

Add .NET 9 + EF 9 support #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.0.x
dotnet-version: |
8.0.x
9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand All @@ -46,7 +48,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
- name: Pack
run: |
dotnet pack -v normal -c Debug --include-symbols --include-source -p:PackageVersion=4.0.0-pre-$GITHUB_RUN_ID -o nupkg
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
include-prerelease: True
- name: Create Release NuGet package
run: |
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Nullable>enable</Nullable>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<NoWarn>CS1591</NoWarn>
<NuGetAudit>false</NuGetAudit>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

Expand Down
27 changes: 17 additions & 10 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Basic.Reference.Assemblies.Net80" Version="1.4.5" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.2" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Basic.Reference.Assemblies.Net80" Version="1.7.9" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="ScenarioTests.XUnit" Version="1.0.1" />
<PackageVersion Include="Verify.Xunit" Version="22.5.0" />
<PackageVersion Include="xunit" Version="2.6.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.4" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.400"
"version": "9.0.100"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using EntityFrameworkCore.Projectables.Extensions;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
Expand All @@ -12,9 +11,10 @@ namespace EntityFrameworkCore.Projectables.Services
{
public sealed class ProjectableExpressionReplacer : ExpressionVisitor
{
readonly IProjectionExpressionResolver _resolver;
readonly ExpressionArgumentReplacer _expressionArgumentReplacer = new();
readonly Dictionary<MemberInfo, LambdaExpression?> _projectableMemberCache = new();
private readonly IProjectionExpressionResolver _resolver;
private readonly ExpressionArgumentReplacer _expressionArgumentReplacer = new();
private readonly Dictionary<MemberInfo, LambdaExpression?> _projectableMemberCache = new();
private IQueryProvider? _currentQueryProvider;
private bool _disableRootRewrite;
private IEntityType? _entityType;

Expand Down Expand Up @@ -60,6 +60,9 @@ bool TryGetReflectedExpression(MemberInfo memberInfo, [NotNullWhen(true)] out La
public Expression? Replace(Expression? node)
{
_disableRootRewrite = false;
_currentQueryProvider = null;
_entityType = null;

var ret = Visit(node);

if (_disableRootRewrite)
Expand Down Expand Up @@ -190,6 +193,29 @@ protected override Expression VisitMethodCall(MethodCallExpression node)

protected override Expression VisitMember(MemberExpression node)
{
// Evaluate captured variables in closures that contain EF queries to inline them into the main query
if (node.Expression is ConstantExpression constant &&
constant.Type.Attributes.HasFlag(TypeAttributes.NestedPrivate) &&
Attribute.IsDefined(constant.Type, typeof(CompilerGeneratedAttribute), inherit: true))
{
try
{
var value = Expression
.Lambda<Func<object>>(Expression.Convert(node, typeof(object)))
.Compile()
.Invoke();

if (value is IQueryable queryable && ReferenceEquals(queryable.Provider, _currentQueryProvider))
{
return Visit(queryable.Expression);
}
}
catch
{
// Ignore evaluation exceptions - continue with normal processing
}
}

var nodeExpression = node.Expression switch {
UnaryExpression { NodeType: ExpressionType.Convert, Type: { IsInterface: true } type, Operand: { } operand }
when type.IsAssignableFrom(operand.Type)
Expand Down Expand Up @@ -232,6 +258,7 @@ protected override Expression VisitExtension(Expression node)
if (node is EntityQueryRootExpression root)
{
_entityType = root.EntityType;
_currentQueryProvider = root.QueryProvider;
}

return base.VisitExtension(node);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DECLARE @__validArray_0 nvarchar(4000) = N'[1,2,3]';

SELECT [t].[Id]
FROM [TestEntity] AS [t]
WHERE [t].[Id] IN (
SELECT [v].[value]
FROM OPENJSON(@__validArray_0) WITH ([value] int '$') AS [v]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DECLARE @__validList_0 nvarchar(4000) = N'[1,2,3]';

SELECT [t].[Id]
FROM [TestEntity] AS [t]
WHERE [t].[Id] IN (
SELECT [v].[value]
FROM OPENJSON(@__validList_0) WITH ([value] int '$') AS [v]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT [t].[Id]
FROM [TestEntity] AS [t]
WHERE [t].[Id] IN (1, 2, 3)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SELECT [o1].[RecordDate]
FROM [User] AS [u]
INNER JOIN (
SELECT [o0].[RecordDate], [o0].[UserId]
FROM (
SELECT [o].[RecordDate], [o].[UserId], ROW_NUMBER() OVER(PARTITION BY [o].[UserId] ORDER BY [o].[RecordDate] DESC) AS [row]
FROM [Order] AS [o]
) AS [o0]
WHERE [o0].[row] <= 2
) AS [o1] ON [u].[Id] = [o1].[UserId]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SELECT [o1].[Id], [o1].[RecordDate], [o1].[UserId]
FROM [User] AS [u]
LEFT JOIN (
SELECT [o0].[Id], [o0].[RecordDate], [o0].[UserId]
FROM (
SELECT [o].[Id], [o].[RecordDate], [o].[UserId], ROW_NUMBER() OVER(PARTITION BY [o].[UserId] ORDER BY [o].[RecordDate] DESC) AS [row]
FROM [Order] AS [o]
) AS [o0]
WHERE [o0].[row] <= 1
) AS [o1] ON [u].[Id] = [o1].[UserId]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT (
SELECT TOP(1) [o].[RecordDate]
FROM [Order] AS [o]
WHERE [u].[Id] = [o].[UserId]
ORDER BY [o].[RecordDate] DESC)
FROM [User] AS [u]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id] + 2
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SELECT [e1].[Id]
FROM [Entity] AS [e]
OUTER APPLY (
SELECT TOP(1) [e0].[Id]
FROM [Entity] AS [e0]
WHERE [e0].[Id] > [e].[Id]
) AS [e1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id] * [e].[Id]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id] + 1
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id] + 1 + 1
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DECLARE @__key_0 varchar(11) = 'x';

SELECT [c].[Id]
FROM [ConcreteEntity] AS [c]
WHERE CONVERT(varchar(11), [c].[Id]) = @__key_0
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SELECT CASE
WHEN [e].[Id] >= 0 THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END, [e].[Id], [e].[Name]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT CAST(1 AS bit), [e].[Id], [e].[Name]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT CAST([c].[Age] AS float) / [c].[AverageLifespan] AS [LifeProgression], CAST([c].[MentalAge] AS float) / [c].[AverageLifespan] AS [MentalLifeProgression]
FROM [Cat] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 4
FROM [Concrete] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [Concrete] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [Concrete] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [MoreConcrete] AS [m]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [MoreConcrete] AS [m]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [Concrete] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 2
FROM [Concrete] AS [c]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT [c].[Id]
FROM [BaseProvider] AS [b]
INNER JOIN [Concrete] AS [c] ON [b].[Id] = [c].[BaseProviderId]
Original file line number Diff line number Diff line change
@@ -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]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Runtime.CompilerServices;

namespace EntityFrameworkCore.Projectables.FunctionalTests
{
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Initialize()
{
#if !NET8_0
VerifierSettings.UniqueForTargetFrameworkAndVersion();
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT 7
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT CAST(LEN([e].[Name]) AS int)
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SELECT [e2].[Id], [e2].[EntityId], [e2].[Name]
FROM [Entity] AS [e]
LEFT JOIN (
SELECT [e1].[Id], [e1].[EntityId], [e1].[Name]
FROM (
SELECT [e0].[Id], [e0].[EntityId], [e0].[Name], ROW_NUMBER() OVER(PARTITION BY [e0].[EntityId] ORDER BY [e0].[Id]) AS [row]
FROM [Entity] AS [e0]
) AS [e1]
WHERE 0 < [e1].[row] AND [e1].[row] <= 1
) AS [e2] ON [e].[Id] = [e2].[EntityId]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Name]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT CAST(LEN([e].[Name]) AS int)
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SELECT CAST(1 AS bit), [e].[Id], [e0].[Id], [e0].[EntityId], [e0].[Name], [e3].[Id], [e3].[EntityId], [e3].[Name]
FROM [Entity] AS [e]
LEFT JOIN [Entity] AS [e0] ON [e].[Id] = [e0].[EntityId]
LEFT JOIN (
SELECT [e2].[Id], [e2].[EntityId], [e2].[Name]
FROM (
SELECT [e1].[Id], [e1].[EntityId], [e1].[Name], ROW_NUMBER() OVER(PARTITION BY [e1].[EntityId] ORDER BY [e1].[Id]) AS [row]
FROM [Entity] AS [e1]
) AS [e2]
WHERE 0 < [e2].[row] AND [e2].[row] <= 1
) AS [e3] ON [e].[Id] = [e3].[EntityId]
ORDER BY [e].[Id]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Name]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id]
FROM [Entity] AS [e]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT [e].[Id], (
SELECT COUNT(*)
FROM [Entity] AS [e0]
WHERE [e0].[Id] * 5 = 5) AS [TotalCount]
FROM [Entity] AS [e]
WHERE [e].[Id] * 5 = 5
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT [e].[Id], (
SELECT COUNT(*)
FROM [Entity] AS [e0]
WHERE [e0].[Id] * 5 = 5) AS [TotalCount]
FROM [Entity] AS [e]
WHERE [e].[Id] * 5 = 5
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SELECT [e].[Id], [e].[Id] * 5
FROM [Entity] AS [e]
Loading
Loading