Is there a way to run EF Core RC2 tools from published DLL?

Unfortunately EF Core migration s*cks, a lot… I have seen tons of solutions for this but lets do a list of them. So here is what you can do to run and deploy EF migrations without Visual Studio. None of the below is perfect solution all have some caveats:

  1. Use EF Core Tools here is a link to the official MS site which explains how to install and use it.
  • Pros: MS official tool. Supported in all version of .NET Core.
  • Cons: It seems like the successor of EF6 “Migrate.exe”. But it is not! Currently it is not possible to use this tool without the actual source code (.csproj). Which is not really a good fit for Live/Prod deployments. Usually you don’t have C# projects on your DB Server.
  1. dotnet exec I have tried to make sense of the huge amount of poorly documented parameters. And failed to run migrations until found this script. The name suggest .NET core 2.1 but I have used it with 3.0 and worked. UPDATE: did not run it with .NET 5
  • Pros: It can be used like EF6 “migrate.exe”. Finally migration works without the source code. And most probably this is the only way to do migration from script and using an Assembly.
  • Cons: Very hard to set up the script, and easy to miss one parameter. Not really documented solution and might change .NET Core version to version. Also most probably you will need to change your code as well. You have to implement IDesignTimeDbContextFactory<DbContext> interface in order to make it work. Also make sure you have EF.dll and Microsoft.EntityFrameworkCore.Design.dll on your deploy server. The linked script is looking for those in numerous folders. Best is to copy it during build from your .nuget folders to your artifact. Sounds complicated, yes it is… But linked script helps a lot.
  1. Add EF migration to your Startup.cs or any point where your code start running and has access to a DBContext. Use dbContext.Database.Migrate();
  • Pros: Migrations happens automatically every time and nothing else had to be done.
  • Cons: Migrations happens automatically every time… The problem you might don’t want to that happen. Also it will run on every App start. So your startup time will be very bad.
  1. Custom app. It is similar to the previous solution (point 3.). So you use .NET code to run migration. But instead of putting it into your app you should create a small console app and call migrate in that one. You have to build this app and put into the Artifact to run it during the deployment.
  • Pros: No script involved. You can call it any time in your deployment pipeline. So your real app startup time not suffers from it.
  • Cons: You have to maintain, build and package an application just to do EF Core migrations.
  1. If you are using Azure Devops for deploy, you can use extension like this. Or just search Azure Devops Marketplace for one.
  • Pros: it should work 🙂 Haven’t tried any of them and don’t know what they do. (I’m pretty sure they are also using ‘dotnet exec’ point 2.)
  • Cons: Not everyone can have access to Live/Prod from Azure Devops.
  1. Generate SQL script: If none of the above works you can generate a migration SQL and run it later. Run EF tool with “script” param: dotnet ef migrations script --output <pathAndFile>.sql --context <DbContextName> --idempotent. The output is an SQL file which can be executed manually or by a script in CI/CD pipeline.
  • Pros: it is perfect solution if you don’t have access or schema change rights to prod DB only DBAs. You can provide DBAs with a “safe and secure” SQL file to run…
  • Cons: very important to emphasize this solution must run in working dir where your .csproj file is. So it requires source code! Also you have to change your code a bit. Need to implement IDesignTimeDbContextFactory<DbContext>.

UPDATE: In .NET 5 there is some improvements. It is now easier to implement and make use of IDesignTimeDbContextFactory but most importantly Microsoft fixed this bug. Now it is possible to pass an SQL connection string as args. So if you implemented IDesignTimeDbContextFactory<T> it is simple to use it with .NET CLI and EF tool:

dotnet ef database update --context <DbContextName> --project "**/<ProjectName>.csproj" -- "<SQL connection will be passed into args[0]>"

Also important to emphasize this works only with .NET 5 and requires source code as well! You can also use it with Option 6 (generate SQL script).

Second annoying issue once implemented IDesignTimeDbContextFactory<T> this will be discovered by ALL ef commands (even commands run from Visual Studio during development). If you require SQL connection string from args[0] you have to pass it in during development migrations add or for any other ef command!

Sorry the list got very long. But hope it helps.

Leave a Comment