Отладка Обновления Консоли Диспетчера Пакетов-Метод Заполнения Базы Данных
Я хотел отладить метод Seed() в моем классе конфигурации базы данных Entity Framework при запуске update-database из консоли диспетчера пакетов, но не знал, как это сделать. Я хотел поделиться решением с другими, если у них есть такая же проблема.
7 ответов:
здесь вопрос С решение, которое работает очень хорошо.
Это не требуетThread.Sleep
.
Просто запускает отладчик с помощью этого кода.вырезано из ответа
if (!System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Launch();
способ, которым я решил это, состоял в том, чтобы открыть новый экземпляр Visual Studio, а затем открыть то же решение в этом новом экземпляре Visual Studio. Затем я подключил отладчик в этом новом экземпляре к старому экземпляру (devenv.exe)при выполнении команды update-database. Это позволило мне отладить метод Seed.
просто чтобы убедиться, что я не пропустил точку останова, не присоединившись вовремя, я добавил поток.Спите до точки останова.
надеюсь, это поможет кто-то.
Если вам нужно получить значение конкретной переменной, быстрый Хак должен бросить исключение:
throw new Exception(variable);
более чистое решение (я думаю, для этого требуется EF 6) будет IMHO вызывать update-database из кода:
var configuration = new DbMigrationsConfiguration<TContext>(); var databaseMigrator = new DbMigrator(configuration); databaseMigrator.Update();
Это позволяет отлаживать начальный метод.
вы можете сделать еще один шаг и построить модульный тест (или, точнее, интеграционный тест), который создает пустую тестовую базу данных, применяет все миграции EF, запускает метод Seed и снова отбрасывает тестовую базу данных:
var configuration = new DbMigrationsConfiguration<TContext>(); Database.Delete("TestDatabaseNameOrConnectionString"); var databaseMigrator = new DbMigrator(configuration); databaseMigrator.Update(); Database.Delete("TestDatabaseNameOrConnectionString");
но будьте осторожны, чтобы не запустить это против вашего разработка базы данных!
Я знаю, что это старый вопрос, но если все, что вам нужно, это сообщения, и вы не хотите включать ссылки на WinForms в свой проект, я сделал несколько простых окон отладки, где я могу отправлять события трассировки.
для более серьезной и пошаговой отладки я открою другой экземпляр Visual Studio, но это не обязательно для простых вещей.
это весь код:
SeedApplicationContext.cs
using System; using System.Data.Entity; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; namespace Data.Persistence.Migrations.SeedDebug { public class SeedApplicationContext<T> : ApplicationContext where T : DbContext { private class SeedTraceListener : TraceListener { private readonly SeedApplicationContext<T> _appContext; public SeedTraceListener(SeedApplicationContext<T> appContext) { _appContext = appContext; } public override void Write(string message) { _appContext.WriteDebugText(message); } public override void WriteLine(string message) { _appContext.WriteDebugLine(message); } } private Form _debugForm; private TextBox _debugTextBox; private TraceListener _traceListener; private readonly Action<T> _seedAction; private readonly T _dbcontext; public Exception Exception { get; private set; } public bool WaitBeforeExit { get; private set; } public SeedApplicationContext(Action<T> seedAction, T dbcontext, bool waitBeforeExit = false) { _dbcontext = dbcontext; _seedAction = seedAction; WaitBeforeExit = waitBeforeExit; _traceListener = new SeedTraceListener(this); CreateDebugForm(); MainForm = _debugForm; Trace.Listeners.Add(_traceListener); } private void CreateDebugForm() { var textbox = new TextBox {Multiline = true, Dock = DockStyle.Fill, ScrollBars = ScrollBars.Both, WordWrap = false}; var form = new Form {Font = new Font(@"Lucida Console", 8), Text = "Seed Trace"}; form.Controls.Add(tb); form.Shown += OnFormShown; _debugForm = form; _debugTextBox = textbox; } private void OnFormShown(object sender, EventArgs eventArgs) { WriteDebugLine("Initializing seed..."); try { _seedAction(_dbcontext); if(!WaitBeforeExit) _debugForm.Close(); else WriteDebugLine("Finished seed. Close this window to continue"); } catch (Exception e) { Exception = e; var einner = e; while (einner != null) { WriteDebugLine(string.Format("[Exception {0}] {1}", einner.GetType(), einner.Message)); WriteDebugLine(einner.StackTrace); einner = einner.InnerException; if (einner != null) WriteDebugLine("------- Inner Exception -------"); } } } protected override void Dispose(bool disposing) { if (disposing && _traceListener != null) { Trace.Listeners.Remove(_traceListener); _traceListener.Dispose(); _traceListener = null; } base.Dispose(disposing); } private void WriteDebugText(string message) { _debugTextBox.Text += message; Application.DoEvents(); } private void WriteDebugLine(string message) { WriteDebugText(message + Environment.NewLine); } } }
и на вашем стандарт конфигурации.cs
// ... using System.Windows.Forms; using Data.Persistence.Migrations.SeedDebug; // ... namespace Data.Persistence.Migrations { internal sealed class Configuration : DbMigrationsConfiguration<MyContext> { public Configuration() { // Migrations configuration here } protected override void Seed(MyContext context) { // Create our application context which will host our debug window and message loop var appContext = new SeedApplicationContext<MyContext>(SeedInternal, context, false); Application.Run(appContext); var e = appContext.Exception; Application.Exit(); // Rethrow the exception to the package manager console if (e != null) throw e; } // Our original Seed method, now with Trace support! private void SeedInternal(MyContext context) { // ... Trace.WriteLine("I'm seeding!") // ... } } }
отладка-это одно, но не забудь позвонить: контекст.Обновление()
также не оборачивайте в try catch без хорошего внутреннего исключения разлива console.
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code-first с catch (DbEntityValidationException ex)