Debugging Package Manager Console Update-Database Seed Method
Chciałem debugować metodę Seed() w mojej klasie konfiguracji bazy danych Entity Framework podczas uruchamiania update-database z konsoli Menedżera pakietów, ale nie wiedziałem jak to zrobić. Chciałem podzielić się rozwiązaniem z innymi w przypadku, gdy mają ten sam problem.
7 answers
Oto podobne pytanie z rozwiązaniem, które działa naprawdę dobrze.
Nie wymaga Thread.Sleep
.
Po prostu uruchamia debugger używając tego kodu.
Wycięte z odpowiedzi
if (!System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Launch();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-25 07:35:47
Sposobem, w jaki to rozwiązałem, było otwarcie nowej instancji Visual Studio, a następnie otwarcie tego samego rozwiązania w nowej instancji Visual Studio. Następnie podłączyłem debugger w tej nowej instancji do starej instancji (devenv.exe) podczas uruchamiania polecenia update-database. To pozwoliło mi debugować metodę Seed.
Aby upewnić się, że nie przegapiłem punktu przerwania, nie dołączając się na czas, dodałem wątek.Spać przed punktem przerwania.
Mam nadzieję, że to komuś pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-23 15:52:44
Jeśli chcesz uzyskać wartość określonej zmiennej, szybkim włamaniem jest rzucenie wyjątku:
throw new Exception(variable);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-18 11:42:17
Czystszym rozwiązaniem (chyba wymaga to EF 6) byłoby IMHO wywołanie update-database z kodu:
var configuration = new DbMigrationsConfiguration<TContext>();
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
To pozwala debugować metodę Seed.
Możesz pójść o krok dalej i zbudować test jednostkowy (a dokładniej test integracyjny), który utworzy pustą bazę testową, zastosuje wszystkie migracje EF, uruchomi metodę Seed i ponownie upuści bazę testową:
var configuration = new DbMigrationsConfiguration<TContext>();
Database.Delete("TestDatabaseNameOrConnectionString");
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
Database.Delete("TestDatabaseNameOrConnectionString");
Ale uważaj, aby nie uruchomić tego z bazy danych rozwoju!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 10:02:20
Wiem, że to stare pytanie, ale jeśli wszystko, co chcesz to wiadomości, i nie obchodzi cię, aby zawierać odniesienia do WinForms w swoim projekcie, zrobiłem proste Okno debugowania, gdzie mogę wysłać śledzenie zdarzeń.
Dla poważniejszego i krok po kroku debugowania, otworzę kolejną instancję Visual Studio, ale nie jest to konieczne dla prostych rzeczy.
To jest cały kod:
Seed Applicationkontekst.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);
}
}
}
I na swoim standardzie Konfiguracja.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!")
// ...
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 06:45:29
Uh debugowanie to jedno, ale nie zapomnij zadzwonić: kontekst.Update ()
Również nie owijaj spróbuj złapać bez dobrych wewnętrznych WYJĄTKÓW rozlać do konsoli.
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code-first
with catch (DbEntityValidationException ex)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 00:52:08
Mam 2 obejścia (Bez Debugger.Launch()
Ponieważ mi nie działa):
Aby wydrukować wiadomość w konsoli Menedżera pakietów, użyj wyjątku:
throw new Exception("Your message");
Innym sposobem jest wypisanie wiadomości w pliku poprzez utworzenie
cmd
procesu:
// Logs to file {solution folder}\seed.log data from Seed method (for DEBUG only)
private void Log(string msg)
{
string echoCmd = $"/C echo {DateTime.Now} - {msg} >> seed.log";
System.Diagnostics.Process.Start("cmd.exe", echoCmd);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 13:28:50