Skip to content

Commit 0eaf687

Browse files
committed
Add publish integration for precompiled queries
1 parent f557e65 commit 0eaf687

File tree

4 files changed

+136
-30
lines changed

4 files changed

+136
-30
lines changed

src/EFCore.Tasks/Tasks/Internal/OperationTaskBase.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public abstract class OperationTaskBase : Build.Utilities.ToolTask
5151
/// </summary>
5252
public ITaskItem? DataDir { get; set; }
5353

54+
/// <summary>
55+
/// The target project.
56+
/// </summary>
57+
public ITaskItem? Project { get; set; }
58+
5459
/// <summary>
5560
/// The project directory.
5661
/// </summary>
@@ -197,6 +202,12 @@ protected override string GenerateCommandLineCommands()
197202
args.Add(Path.ChangeExtension(StartupAssembly.ItemSpec, ".dll"));
198203
}
199204

205+
if (Project != null)
206+
{
207+
args.Add("--project");
208+
args.Add(Project.ItemSpec);
209+
}
210+
200211
if (ProjectDir != null)
201212
{
202213
args.Add("--project-dir");

src/EFCore.Tasks/Tasks/OptimizeDbContext.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ public class OptimizeDbContext : OperationTaskBase
2727
/// </summary>
2828
public ITaskItem? OutputDir { get; set; }
2929

30+
/// <summary>
31+
/// Don't generate a compiled model.
32+
/// </summary>
33+
public bool NoScaffold { get; set; }
34+
35+
/// <summary>
36+
/// Generate precompiled queries.
37+
/// </summary>
38+
public bool PrecompileQueries { get; set; }
39+
3040
/// <summary>
3141
/// Generated files that should be include in the build.
3242
/// </summary>
@@ -56,12 +66,22 @@ public override bool Execute()
5666
}
5767

5868
var dbContextName = MsBuildUtilities.TrimAndGetNullForEmpty(DbContextName);
59-
if(dbContextName != null)
69+
if (dbContextName != null)
6070
{
6171
AdditionalArguments.Add("--context");
6272
AdditionalArguments.Add(dbContextName);
6373
}
6474

75+
if (NoScaffold)
76+
{
77+
AdditionalArguments.Add("--no-scaffold");
78+
}
79+
80+
if (PrecompileQueries)
81+
{
82+
AdditionalArguments.Add("--precompile-queries");
83+
}
84+
6585
AdditionalArguments.Add("--suffix");
6686
AdditionalArguments.Add(".g");
6787

src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<_TaskTargetFramework Condition="'$(MSBuildRuntimeType)' == 'core'">net8.0</_TaskTargetFramework>
55
<_TaskTargetFramework Condition="'$(MSBuildRuntimeType)' != 'core'">net472</_TaskTargetFramework>
66
<_EFCustomTasksAssembly>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory), '..\tasks\$(_TaskTargetFramework)\$(MSBuildThisFileName).dll'))</_EFCustomTasksAssembly>
7-
<EFOptimizeContext Condition="'$(EFOptimizeContext)'==''">false</EFOptimizeContext>
7+
<EFScaffoldModelStage Condition="'$(EFScaffoldModelStage)'==''">publish</EFScaffoldModelStage>
8+
<EFPrecompileQueriesStage Condition="'$(EFPrecompileQueriesStage)'==''">publish</EFPrecompileQueriesStage>
89
<EFStartupProject Condition="'$(EFStartupProject)'==''">$(MSBuildProjectFullPath)</EFStartupProject>
910
</PropertyGroup>
1011

src/EFCore.Tasks/buildTransitive/Microsoft.EntityFrameworkCore.Tasks.targets

Lines changed: 102 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<PropertyGroup>
55
<_FullOutputPath>$([MSBuild]::NormalizePath($(MSBuildProjectDirectory), '$(OutputPath)'))</_FullOutputPath>
66
<_FullIntermediateOutputPath>$([MSBuild]::NormalizePath($(MSBuildProjectDirectory), '$(IntermediateOutputPath)'))</_FullIntermediateOutputPath>
7-
<EFGeneratedSourcesFile Condition="'$(EFGeneratedSourcesFile)' == ''">$(_FullIntermediateOutputPath)$(AssemblyName).EFGeneratedSources.txt</EFGeneratedSourcesFile>
7+
<EFGeneratedSourcesBuildFile Condition="'$(EFGeneratedSourcesBuildFile)' == ''">$(_FullIntermediateOutputPath)$(AssemblyName).EFGeneratedSources.Build.txt</EFGeneratedSourcesBuildFile>
8+
<EFGeneratedSourcesPublishFile Condition="'$(EFGeneratedSourcesPublishFile)' == ''">$(_FullIntermediateOutputPath)$(AssemblyName).EFGeneratedSources.Publish.txt</EFGeneratedSourcesPublishFile>
89
<EFProjectsToOptimizePath Condition="'$(EFProjectsToOptimizePath)' == ''">$(_FullIntermediateOutputPath)EFProjectsToOptimize\</EFProjectsToOptimizePath>
910
<_AssemblyFullName>$(_FullOutputPath)$(AssemblyName).dll</_AssemblyFullName>
1011
<CoreCompileDependsOn>$(CoreCompileDependsOn);_EFPrepareForCompile</CoreCompileDependsOn>
@@ -14,10 +15,29 @@
1415
<_AssemblyFullName>$(_FullOutputPath)$(AssemblyName).exe</_AssemblyFullName>
1516
</PropertyGroup>
1617

18+
<Target Name="_EFGenerateFilesAfterBuild"
19+
AfterTargets="Build"
20+
Condition="Exists($(EFProjectsToOptimizePath)) And '$(_EFGenerationStage)'==''">
21+
<MSBuild Projects="$(MSBuildProjectFullPath)"
22+
Targets="_EFGenerateFiles"
23+
BuildInParallel="$(BuildInParallel)"
24+
ContinueOnError="$(ContinueOnError)"
25+
Properties="Configuration=$(Configuration);Platform=$(Platform);_EFGenerationStage=build" />
26+
</Target>
27+
28+
<Target Name="_EFGenerateFilesBeforePublish"
29+
AfterTargets="GetCopyToPublishDirectoryItems"
30+
BeforeTargets="GeneratePublishDependencyFile"
31+
Condition="Exists($(EFProjectsToOptimizePath)) And '$(_EFGenerationStage)'==''">
32+
<MSBuild Projects="$(MSBuildProjectFullPath)"
33+
Targets="_EFGenerateFiles"
34+
BuildInParallel="$(BuildInParallel)"
35+
ContinueOnError="$(ContinueOnError)"
36+
Properties="Configuration=$(Configuration);Platform=$(Platform);_EFGenerationStage=publish" />
37+
</Target>
38+
1739
<!-- Invokes OptimizeDbContext on projects that had changes since the last time they were optimized -->
18-
<Target Name="_EFGenerateFiles"
19-
AfterTargets="Build"
20-
Condition="Exists($(EFProjectsToOptimizePath)) And '$(_InEFGenerateFiles)'!='true'">
40+
<Target Name="_EFGenerateFiles">
2141
<ItemGroup>
2242
<_EFProjectsToOptimizeFiles Include="$(EFProjectsToOptimizePath)*.*" />
2343
</ItemGroup>
@@ -31,14 +51,16 @@
3151
<!-- The startup assembly used for file generation should be compiled without using AOT mode -->
3252
<MSBuild Projects="$(MSBuildProjectFullPath)"
3353
Targets="Build"
34-
BuildInParallel="true"
54+
BuildInParallel="$(BuildInParallel)"
55+
ContinueOnError="$(ContinueOnError)"
3556
Condition="'$(PublishAot)'=='true'"
36-
Properties="Configuration=$(Configuration);Platform=$(Platform);EFOptimizeContext=false;PublishAot=false" />
57+
Properties="Configuration=$(Configuration);Platform=$(Platform);PublishAot=false;_EFGenerationStage=$(_EFGenerationStage)" />
3758

3859
<MSBuild Projects="@(_EFProjectsToOptimize)"
3960
Targets="OptimizeDbContext"
40-
BuildInParallel="true"
41-
Properties="Configuration=$(Configuration);Platform=$(Platform);EFStartupAssembly=$(_AssemblyFullName)" />
61+
BuildInParallel="$(BuildInParallel)"
62+
ContinueOnError="$(ContinueOnError)"
63+
Properties="Configuration=$(Configuration);Platform=$(Platform);EFStartupAssembly=$(_AssemblyFullName);_EFGenerationStage=$(_EFGenerationStage)" />
4264

4365
<ItemGroup>
4466
<_EFProjectsToOptimize Remove="$(MSBuildProjectFullPath)" />
@@ -47,25 +69,24 @@
4769
<!-- This assumes that the optimized projects are dependencies, so the current project needs to be recompiled too -->
4870
<MSBuild Projects="$(MSBuildProjectFullPath)"
4971
Targets="Build"
50-
BuildInParallel="true"
72+
BuildInParallel="$(BuildInParallel)"
73+
ContinueOnError="$(ContinueOnError)"
5174
Condition="@(_EFProjectsToOptimize->Count()) &gt; 0"
52-
Properties="Configuration=$(Configuration);Platform=$(Platform);_InEFGenerateFiles=true" />
75+
Properties="Configuration=$(Configuration);Platform=$(Platform);_EFGenerationStage=$(_EFGenerationStage)" />
5376
</Target>
5477

55-
<Target Name="OptimizeDbContext"
56-
Inputs="$(_AssemblyFullName)"
57-
Outputs="$(EFGeneratedSourcesFile)"
58-
Returns="$(_EFGeneratedFiles)">
78+
<Target Name="OptimizeDbContext">
5979
<PropertyGroup>
6080
<EFRootNamespace Condition="'$(EFRootNamespace)'==''">$(RootNamespace)</EFRootNamespace>
6181
<EFRootNamespace Condition="'$(EFRootNamespace)'==''">$(AssemblyName)</EFRootNamespace>
6282
<EFTargetNamespace Condition="'$(EFTargetNamespace)'==''">$(EFRootNamespace)</EFTargetNamespace>
6383
<EFOutputDir Condition="'$(EFOutputDir)'==''">$(_FullIntermediateOutputPath)</EFOutputDir>
64-
<EFNullable>false</EFNullable>
65-
</PropertyGroup>
66-
67-
<PropertyGroup Condition="'$(Nullable)'=='enable' Or '$(Nullable)'=='annotations'">
68-
<EFNullable>true</EFNullable>
84+
<_EFNoScaffold>true</_EFNoScaffold>
85+
<_EFNoScaffold Condition="'$(_EFGenerationStage)'=='$(EFScaffoldModelStage)'">false</_EFNoScaffold>
86+
<_EFPrecompileQueries>false</_EFPrecompileQueries>
87+
<_EFPrecompileQueries Condition="'$(_EFGenerationStage)'=='$(EFPrecompileQueriesStage)'">true</_EFPrecompileQueries>
88+
<EFNullable Condition="'$(Nullable)'=='enable' Or '$(Nullable)'=='annotations'">true</EFNullable>
89+
<EFNullable Condition="'$(EFNullable)'==''">false</EFNullable>
6990
</PropertyGroup>
7091

7192
<OptimizeDbContext Assembly="$(_AssemblyFullName)"
@@ -79,22 +100,43 @@
79100
Language="$(Language)"
80101
Nullable="$(EFNullable)"
81102
OutputDir="$(EFOutputDir)"
82-
ProjectDir="$(MSBuildProjectDirectory)">
103+
Project="$(MSBuildProjectFullPath)"
104+
ProjectDir="$(MSBuildProjectDirectory)"
105+
NoScaffold="$(_EFNoScaffold)"
106+
PrecompileQueries="$(_EFPrecompileQueries)">
83107
<Output TaskParameter="GeneratedFiles" PropertyName="_EFGeneratedFiles" />
84108
</OptimizeDbContext>
85109

86-
<Delete Files="$(EFGeneratedSourcesFile)" />
110+
<Delete Files="$(EFGeneratedSourcesBuildFile)"
111+
Condition="'$(_EFGenerationStage)'=='build'"/>
112+
<Delete Files="$(EFGeneratedSourcesPublishFile)"
113+
Condition="'$(_EFGenerationStage)'=='publish'"/>
87114

88115
<CallTarget Targets="Build"/>
89116

90-
<WriteLinesToFile File="$(EFGeneratedSourcesFile)" Lines="$(_EFGeneratedFiles)"/>
117+
<WriteLinesToFile File="$(EFGeneratedSourcesBuildFile)"
118+
Lines="$(_EFGeneratedFiles)"
119+
Condition="'$(_EFGenerationStage)'=='build'"/>
120+
<WriteLinesToFile File="$(EFGeneratedSourcesPublishFile)"
121+
Lines="$(_EFGeneratedFiles)"
122+
Condition="'$(_EFGenerationStage)'=='publish'"/>
123+
</Target>
124+
125+
<Target Name="_EFValidateProperties"
126+
BeforeTargets="CoreCompile">
127+
<Error Condition="'$(EFScaffoldModelStage)'=='publish' And '$(EFPrecompileQueriesStage)'=='build'"
128+
Text="If %24(EFScaffoldModelStage) is set to 'publish' then %24(EFPrecompileQueriesStage) must also be set to 'publish'."/>
91129
</Target>
92130

93131
<!-- Read the previously generated files -->
94132
<Target Name="_EFReadGeneratedFilesList"
95-
BeforeTargets="_EFProcessGeneratedFiles;_EFCleanupGeneratedFiles"
96-
Condition="'$(EFOptimizeContext)'=='true' And Exists($(EFGeneratedSourcesFile))">
97-
<ReadLinesFromFile File="$(EFGeneratedSourcesFile)">
133+
BeforeTargets="_EFProcessGeneratedFiles;_EFCleanGeneratedFiles">
134+
<ReadLinesFromFile File="$(EFGeneratedSourcesBuildFile)"
135+
Condition="Exists($(EFGeneratedSourcesBuildFile))">
136+
<Output TaskParameter="Lines" ItemName="_ReadGeneratedFiles"/>
137+
</ReadLinesFromFile>
138+
<ReadLinesFromFile File="$(EFGeneratedSourcesPublishFile)"
139+
Condition="Exists($(EFGeneratedSourcesPublishFile))">
98140
<Output TaskParameter="Lines" ItemName="_ReadGeneratedFiles"/>
99141
</ReadLinesFromFile>
100142

@@ -111,11 +153,11 @@
111153
</ItemGroup>
112154
</Target>
113155

114-
<!-- Removes the outdated generated files from compilation and registers this project for optimization
156+
<!-- Removes the outdated generated files from compilation and registers this project for after-compile optimization
115157
This target has the same Inputs and Outputs as CoreCompile to run only if CoreCompile isn't going to be skipped -->
116158
<Target Name="_EFPrepareForCompile"
117159
DependsOnTargets="_EFProcessGeneratedFiles"
118-
Condition="'$(EFOptimizeContext)'=='true' And '$(_InEFGenerateFiles)'!='true'"
160+
Condition="'$(_EFGenerationStage)'==''"
119161
Inputs="$(MSBuildAllProjects);
120162
@(Compile);
121163
@(_CoreCompileResourceInputs);
@@ -144,11 +186,42 @@
144186
<Compile Remove="@(_EFGeneratedFiles)" />
145187
</ItemGroup>
146188

189+
<Delete Files="$(EFGeneratedSourcesBuildFile)" />
190+
<Delete Files="$(EFGeneratedSourcesPublishFile)" />
191+
192+
<MSBuild Projects="$(EFStartupProject)"
193+
Targets="_EFRegisterProjectToOptimize"
194+
Condition="'$(EFOptimizeContext)'=='true' And ('$(EFScaffoldModelStage)'=='build' Or '$(EFPrecompileQueriesStage)'=='build')"
195+
Properties="Configuration=$(Configuration);Platform=$(Platform);_EFProjectToOptimize=$(MSBuildProjectFullPath)" />
196+
</Target>
197+
198+
<!-- Registers this project for before-publish optimization -->
199+
<Target Name="_EFPrepareForPublish"
200+
BeforeTargets="GetCopyToPublishDirectoryItems"
201+
Condition="'$(_EFGenerationStage)'=='' And ('$(EFScaffoldModelStage)'=='publish' Or '$(EFPrecompileQueriesStage)'=='publish') And ('$(EFOptimizeContext)'=='true' Or ('$(EFOptimizeContext)'=='' And ('$(_EFPublishAOT)'=='true' Or '$(PublishAOT)'=='true')))">
147202
<MSBuild Projects="$(EFStartupProject)"
148203
Targets="_EFRegisterProjectToOptimize"
149204
Properties="Configuration=$(Configuration);Platform=$(Platform);_EFProjectToOptimize=$(MSBuildProjectFullPath)" />
150205
</Target>
151206

207+
<!-- Go through the dependencies to check whether they need code generated for Native AOT -->
208+
<Target Name="_EFPrepareDependenciesForPublishAOT"
209+
BeforeTargets="GetCopyToPublishDirectoryItems"
210+
Condition="'$(PublishAOT)'=='true' And '$(_EFGenerationStage)'=='' and '@(_MSBuildProjectReferenceExistent)' != ''">
211+
<MSBuild
212+
Projects="@(_MSBuildProjectReferenceExistent)"
213+
Targets="_EFPrepareForPublish"
214+
BuildInParallel="$(BuildInParallel)"
215+
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform); %(_MSBuildProjectReferenceExistent.SetTargetFramework); _EFPublishAOT=true"
216+
Condition="'%(_MSBuildProjectReferenceExistent.BuildReference)' == 'true' and '@(ProjectReferenceWithConfiguration)' != '' "
217+
ContinueOnError="$(ContinueOnError)"
218+
SkipNonexistentTargets="true"
219+
RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove)$(_GlobalPropertiesToRemoveFromProjectReferences)">
220+
221+
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedProjectReferencePaths"/>
222+
</MSBuild>
223+
</Target>
224+
152225
<Target Name="_EFRegisterProjectToOptimize">
153226
<PropertyGroup>
154227
<_ProjectName>$([System.IO.Path]::GetFileName('$(_EFProjectToOptimize)'))</_ProjectName>
@@ -159,7 +232,8 @@
159232

160233
<Target Name="_EFCleanGeneratedFiles" AfterTargets="Clean">
161234
<Delete Files="@(_EFGeneratedFiles)" />
162-
<Delete Files="$(EFGeneratedSourcesFile)" />
235+
<Delete Files="$(EFGeneratedSourcesBuildFile)" />
236+
<Delete Files="$(EFGeneratedSourcesPublishFile)" />
163237
<RemoveDir Directories="$(EFProjectsToOptimizePath)" />
164238
</Target>
165239

0 commit comments

Comments
 (0)