2013-05-23 4 views

Odpowiedz

127

Tutaj jest podobne question z rozwiązaniem, które działa bardzo dobrze.
NIE wymaga Thread.Sleep.
Just Uruchamia debuger używając tego kodu.

Wycięta z odpowiedzi

if (!System.Diagnostics.Debugger.IsAttached) 
    System.Diagnostics.Debugger.Launch(); 
+1

I zostały z wykorzystaniem tej metody i działa świetnie. –

+4

działa, ale otwiera nowe studio wizualnych. – tchelidze

16

Sposób, w jaki to rozwiązałem, to otwarcie nowej instancji programu Visual Studio, a następnie otwarcie tego samego rozwiązania w tej nowej instancji programu Visual Studio. Następnie załączam debugger w tej nowej instancji do starej instancji (devenv.exe) podczas uruchamiania komendy update-database. Pozwoliło mi to na debugowanie metody Seed.

Tylko po to, aby upewnić się, że nie przegapiłem punktu przerwania, nie załączając w czasie dodałem Thread.Space przed punktem przerwania.

Mam nadzieję, że to pomoże komuś.

+1

Dzięki, pracował dla mnie. – VivekDev

8

Jeśli trzeba uzyskać wartość konkretnej zmiennej, szybkie Hack jest wyjątek:

throw new Exception(variable); 
+1

Szybkie i brudne :) – DanKodi

2

wiem, że to jest stare pytanie, ale jeśli chcesz tylko wiadomości i nie chcesz dołączać do projektu odnośników do WinForm, zrobiłem proste okno debugowania, w którym mogę wysyłać zdarzenia śledzenia.

Dla bardziej poważnego i szczegółowego debugowania, otworzę kolejną instancję Visual Studio, ale nie jest to konieczne w przypadku prostych rzeczy.

To jest cały kod:

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); 
    } 
    } 
} 

oraz na standardowej Configuration.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!") 
     // ... 
    } 
    } 
} 
+1

Oczywiście, okno debugowania może być tak skomplikowane, jak chcesz (można nawet użyć projektanta do stworzenia kompletnego formularz i przekazać go wokół więc 'metoda SeedInternal' można go używać) – Jcl

1

Uh debugowanie jest jedna rzecz, ale don” t zapomnij zadzwonić: context.Update()

Nie należy również pakować w try catch bez dobrych wewnętrznych wyjątków rozlewania się na konsolę.
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code-first z połowu (DbEntityValidationException ex)

+0

Proszę to sprawdzić [URL] (http://stackoverflow.com/help) będzie przydatna, aby podnieść jakość treści w górę –

3

Czystsze rozwiązanie (myślę, że to wymaga EF 6) IMHO być zadzwonić update-bazy danych z kodu:

var configuration = new DbMigrationsConfiguration<TContext>(); 
var databaseMigrator = new DbMigrator(configuration); 
databaseMigrator.Update(); 

To pozwala ci wyszukiwać błędy Seed metoda.

Możesz wykonać ten krok dalej i skonstruować test jednostkowy (lub dokładniej test integracyjny), który tworzy pustą testową bazę danych, stosuje wszystkie migracje EF, uruchamia metodę Seed i ponownie usuwa testową bazę danych:

var configuration = new DbMigrationsConfiguration<TContext>(); 
Database.Delete("TestDatabaseNameOrConnectionString"); 

var databaseMigrator = new DbMigrator(configuration); 
databaseMigrator.Update(); 

Database.Delete("TestDatabaseNameOrConnectionString"); 

Należy jednak uważać, aby nie uruchamiać tego w bazie danych programistycznych!

0

Mam 2 obejścia (bez Debugger.Launch() ponieważ nie działa dla mnie):

  1. Aby wydrukować wiadomość w konsoli Menedżer pakietów zastosowania wyjątku:
    throw new Exception("Your message");

  2. Innym sposobem jest wydrukuj wiadomość w pliku, tworząc proces: cmd:


    // 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); 
    }