Skip to content
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

Working implementation of precompiled queries #29949

Closed
wants to merge 10 commits into from

Conversation

roji
Copy link
Member

@roji roji commented Dec 30, 2022

Here's a first "semi-complete" working implementation of precompiled queries (#25009), for creating a feature branch. We can use this PR for first discussions.

To test this:

  • Create a console program referencing this branch via <ProjectReference>, and run dotnet ef dbcontext optimize (I've replaced that to do precompiled querying, until we decide on the exact CLI switch (also to make it easier to test without needing a modified dotnet-ef tool)).
  • Alternatively, you can do the precompiled query generation from your console app itself, which makes for a nice inner loop experience (you can debug into it etc.):
Triggering precompilation from your console app
if (args.Length > 0 && args[0] == "regenerate")
{
    var services = new ServiceCollection()
        .AddEntityFrameworkDesignTimeServices()
        .AddDbContextDesignTimeServices(ctx);
    var npgsqlDesignTimeServices = new SqlServerDesignTimeServices();
    npgsqlDesignTimeServices.ConfigureDesignTimeServices(services);
    var serviceProvider = services.BuildServiceProvider();
    var precompiledQueriesCodeGenerator = serviceProvider.GetRequiredService<IPrecompiledQueryCodeGenerator>();
    await precompiledQueriesCodeGenerator.GeneratePrecompiledQueries("/home/roji/projects/test/Test.csproj", ctx, outputDir: "/home/roji/projects/test");
    return;
}
  • This builds the the project using Roslyn; note that this build is in additional to the regular build when invoking dotnet ef. Also, since you're referencing EF as a project reference, this will build EF too (long but only with this test setup).
  • This reports the queries it identified, and generates an EFPrecompiledQueryBootstrapper into the project directory.
  • When you run your console program, any query which was precompiled should be picked up, skipping runtime compilation.
  • It can be useful to configure logging to show when query compilation and execution occur:
optionsBuilder.LogTo(Console.WriteLine, new[] { CoreEventId.QueryCompilationStarting, RelationalEventId.CommandExecuted })

This is by no means complete - I have a list of stuff that still needs to be done (split query, ExecuteUpdate/Delete, SQL queries, possibly some expression tree edge cases...).

To track issues you come across, I suggest posting them as a todo list in #25009 - no need for lots of different issues at this point).

@roji roji requested a review from a team December 30, 2022 16:16

outputDir = Path.GetFullPath(Path.Combine(_projectDir, outputDir ?? ""));

// TODO: Need the project csproj. For now hacking an assumption that the csproj is the same as the assembly name.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @bricelam, can we get the csproj here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you'll need to flow it (MSBuildProjectFile) in from dotnet-ef the same way we do projectDir

* Fix NewArray
* Implement expression list lifting properly (New, Call, Invocation,
  NewArray)
* General cleanup
@roji roji marked this pull request as draft January 2, 2023 15:31
@roji roji deleted the branch dotnet:PrecompiledQueries December 26, 2023 16:40
@roji roji closed this Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants