-
Notifications
You must be signed in to change notification settings - Fork 575
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
Spike WithEntityFrameworkMigration #7894
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Overview
This PR explores adding an extension method, WithEntityFrameworkMigrations, to streamline running Entity Framework migrations by generating a dedicated executable that calls "dotnet ef database update". Key changes include:
- Adding the WithEntityFrameworkMigrations extension method and a corresponding marker interface.
- Updating project initialization in playground files to integrate the new migration mechanism.
- Adjusting namespaces and removing an obsolete DbSetup program in favor of the new approach.
Reviewed Changes
File | Description |
---|---|
src/Aspire.Hosting/EntityFrameworkMigrationExtensions.cs | New extension method for EF migrations with executable creation. |
src/Aspire.Hosting/ApplicationModel/IResourceSupportsEntityFrameworkMigrations.cs | New marker interface enabling migration support. |
playground/waitfor/WaitForSandbox.AppHost/Program.cs | Updated to invoke the new migration method. |
playground/waitfor/WaitForSandbox.ApiService/Model/Entry.cs.cs | Namespace update from Common to ApiService.Model. |
playground/waitfor/WaitForSandbox.ApiService/Program.cs | Namespace update to reflect new model namespace. |
playground/waitfor/WaitForSandbox.ApiService/Model/MyDbContext.cs | Namespace update to reflect new model namespace. |
src/Aspire.Hosting.Azure.PostgreSQL/AzurePostgresFlexibleServerDatabaseResource.cs | Extended resource to support EF migrations. |
playground/waitfor/WaitForSandbox.DbSetup/Program.cs | Removed obsolete DbSetup program. |
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
context.Args.Add("--project"); | ||
context.Args.Add(projectMetadata.ProjectPath); | ||
context.Args.Add("--connection"); | ||
context.Args.Add(builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The argument passed for '--connection' is 'builder', which is not a connection string. Consider passing the actual connection string value obtained from the resource instead.
context.Args.Add(builder); | |
context.Args.Add(builder.GetConnectionString()); |
Copilot is powered by AI, so mistakes are possible. Review output carefully before use.
Ergonomics wise it might make sense to have a WithMigrations(...) extension method which is hand-crafted for each resource type for which we support migrations instead of what I've done here which is trying to make it generic at the Aspire.Hosting package level. This would be better from an ergonomics point of view because we'd be able to do this:
It looks like the MSBuild issues with |
We should figure out the details and push to backport if we think it's needed for this scenario. |
context.Args.Add("update"); | ||
context.Args.Add("--project"); | ||
context.Args.Add(projectMetadata.ProjectPath); | ||
context.Args.Add("--connection"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to pass the --no-build
flag too so it doesn't try to build the project while it's running
I have been doing something very similar to this successfully for a while now: var migrations = builder.AddExecutable("dbMigrations", "dotnet", "../My.Migration.Project")
.WithArgs(
"ef",
"database",
"update",
"--connection",
database.Resource.ConnectionStringExpression,
"--startup-project",
"../My.Api",
"-v",
"--no-build") // As this project is part of the solution, relying on the fact that it has just been built before running the app host
.WaitFor(postgres)
.WithParentRelationship(database)
;
builder.AddProject<My_Api>("api")
.WaitFor(migrations)
.WithEnvironment("MY_ConnectionString", database.Resource.ConnectionStringExpression)
; |
context.Args.Add(builder); | ||
}) | ||
.WaitFor((IResourceBuilder<IResource>)builder); | ||
return builder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if your app wants to wait for migrations to be completed? With thisapproach, your app would need to wait on the migrator resource, but the migrator resource is not returned to the consumer?
As an alternative to running dotnet ef migrate
as a separate process, you could run the migrations in-process via the ResourceReadyEvent
- as the event is blocking, consumers could just wait on the database resource directly, although it would require a bit more code to write, wire up logs, handle errors etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are considering this option as well. The downside of that is that you need to structure your project a certain way. It's all tradeoffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running it in process mean referencing the DbContext and all of the app code from the apphost, which is a non starter.
context.Args.Add("--connection"); | ||
context.Args.Add(builder); | ||
}) | ||
.WaitFor((IResourceBuilder<IResource>)builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does dotnet ef migrate
emit open telemetry?
.WaitFor((IResourceBuilder<IResource>)builder); | |
.WaitFor((IResourceBuilder<IResource>)builder) | |
.WithOtlpExporter() | |
; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a good question.
Co-authored-by: Alex Crome <[email protected]>
DO NOT MERGE
This explores the idea of adding a
WithEntityFrameworkMigrations(...)
extension method which creates an executable that calls out todotnet ef database update
. At the moment this code doesn't work because we are being impacted by the dreaded:But conceptually dynamically adding an executable and passing along the connection string works.