Reputation: 4396
I have some code in my ConfigureServices
that fails when running a migration:
dotnet ef migrations list
I'm trying to add a Certificate but it can't find the file (it works when starting the project as a whole). So is there a way to do something like this:
if (!CurrentEnvironment.IsMigration()) {
doMyStuffThatFailsInMigration()
}
That way I could keep my code as it is but just execute it when not running it in a migration.
Thanks
Upvotes: 14
Views: 3574
Reputation: 787
try this
bool isMigrations = Environment.GetCommandLineArgs()[0].Contains("ef.dll");
Upvotes: 0
Reputation: 69
I came across this same issue, I wish migrations automatically set the environment as "Migration" instead of "Development".
You can try this as it worked for me using .Net 7:
if (!Environment.GetCommandLineArgs().Contains("migrations") &&
!Environment.GetCommandLineArgs().Contains("database"))
{
// Add roles to db on startup for example.
}
Thanks Nikolai Koudelia for the idea in one of the previous answers.
Upvotes: 0
Reputation: 2639
Just set a static flag in the Main method (which is not called by the dotnet-ef tool):
public class Program
{
public static bool IsStartedWithMain { get; private set; }
public static void Main(string[] args)
{
IsStartedWithMain = true;
...
}
}
and then check it when needed:
internal static void ConfigureServices(WebHostBuilderContext context, IServiceCollection services)
{
if (Program.IsStartedWithMain)
{
// do stuff which must not be run upon using the dotnet-ef tool
}
}
EDIT: in Dotnet 6.0 there's no separate ConfigureServices
method. Everything is initialized in the Main method (can be created with dotnet new .. --use-program-main
). In this case a flag can be used for skipping EF stuff:
private static bool IsStartedWithMain =>
Assembly.GetEntryAssembly() == Assembly.GetExecutingAssembly();
Upvotes: 11
Reputation: 4443
My current solution to detecting if a migration has not occurred:
using System.Linq;
// app is of type IApplicationBuilder
// RegisteredDBContext is the DBContext I have dependency injected
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<RegisteredDBContext>();
if (context.Database.GetPendingMigrations().Any())
{
var msg = "There are pending migrations application will not start. Make sure migrations are ran.";
throw new InvalidProgramException(msg);
// Instead of error throwing, other code could happen
}
}
This assumes that the migrations have been synced to the database already. If only EnsureDatabase
has been called, then this approach does not work, because the migrations are all still pending.
There are other method options on the context.Database
. GetMigrations
and GetAppliedMigrations
.
Upvotes: 4