Вы можете использовать метод расширения GetMigrations класса DatabaseFacade
(возвращенный свойством Database
для DbContext
), чтобы получить список ожидающих имен миграции.
Затем вы можете получить услугу IMigrator
и использовать метод Migrate
, передающий каждое целевое имя миграции:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
DbContext db = ...;
var pendingMigrations = db.Database.GetPendingMigrations().ToList();
if (pendingMigrations.Any())
{
var migrator = db.Database.GetService();
foreach (var targetMigration in pendingMigrations)
migrator.Migrate(targetMigration);
}
Это потому, что вы запускаете его через Visual Studio в режиме отладки. Если вы отпустите и установите приложение в другом месте, будет обработан только ваш глобальный обработчик исключений.
Это поведение по дизайну.
Но там есть обход.
Либо вы вызываете Process.GetCurrentProcess().Kill();
внутри обработчика, либо просто не позволяйте обработчику закончить.
Посмотрите пример:
class Program
{
void Run()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("Press enter to exit.");
do
{
(new Thread(delegate()
{
throw new ArgumentException("ha-ha");
})).Start();
} while (Console.ReadLine().Trim().ToLowerInvariant() == "x");
Console.WriteLine("last good-bye");
}
int r = 0;
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Interlocked.Increment(ref r);
Console.WriteLine("handled. {0}", r);
Console.WriteLine("Terminating " + e.IsTerminating.ToString());
Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Name = "Dead thread";
while (true)
Thread.Sleep(TimeSpan.FromHours(1));
//Process.GetCurrentProcess().Kill();
}
static void Main(string[] args)
{
Console.WriteLine("...");
(new Program()).Run();
}
}
Это, конечно, не должно быть по умолчанию для исключений.
Но это должно быть сделано, чтобы излагать исключения изящно.
Обратите внимание, что необработанные исключения по-прежнему довольно смертельны; вы можете реально использовать это только для регистрации или, может быть, поспешного закрытия. Ни этот, ни Application.ThreadException
не могут использоваться как глобальный приемник для ошибок.
. Лучший подход - добавить правильную обработку - например, вокруг всей вашей Main()
логики. Обратите внимание, что даже этот не может поймать несколько исключений, таких как ошибки во время загрузки формы (которые становятся особенно неприятными - вы можете поймать их приложением отладчика, но не без него).
Обычно я использую что-то вроде этого, чтобы попытаться поймать все неожиданные исключения верхнего уровня.
using System;
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> FatalExceptionObject(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> FatalExceptionHandler.Handle(e.Exception);
// whatever you need/want here
Application.Run(new MainWindow());
}
catch (Exception huh)
{
FatalExceptionHandler.Handle(huh);
}
}
static void FatalExceptionObject(object exceptionObject) {
var huh = exceptionObject as Exception;
if (huh == null) {
huh = new NotSupportedException(
"Unhandled exception doesn't derive from System.Exception: "
+ exceptionObject.ToString()
);
}
FatalExceptionHandler.Handle(huh);
}
}
Может быть, это то, что вы тоже найдете полезным? Этот основной код маршрутизирует все три способа обнаружения неожиданных исключений верхнего уровня посредством одного вызова метода. Все, что вам теперь нужно, это статический класс FatalExceptionHandler
, который включает в себя обработку исключений верхнего уровня в методе Handle
.
И действительно, любой разработчик приложений знает, что на самом деле есть только две вещи:
Если вы думаете, что элемент два странных, помните, что мы только потрудились сделать это в первую очередь для действительно исключительных ситуаций. Эти вещи, вероятно, являются ошибками, которые нуждаются в изменениях в вашем приложении, чтобы их можно было точно решить. Любая другая обработка исключений - функциональный вид - должна быть ниже внутри вашего реального программного кода, улавливая определенные виды исключений, если это имеет смысл и обрабатывает их там, как это имеет смысл. Что-нибудь еще должно пузыриться до вашего FatalExceptionHandler
, чтобы сделать себя известным и остановить возможную искалеченную программу от работы из поврежденного состояния
Мертвые программы не говорят лжи ...; -)
e.ExceptionObject
в Exception
без проверки во-первых, поскольку он не всегда будет иметь тип Exception
... вы могли бы создать здесь новый Exception
.
– Sheridan
31 July 2013 в 11:06
Возможно, вы ищете Environment.Exit(int errorcode)