113

Seed()パッケージ マネージャー コンソールから実行するときに、Entity Framework データベース構成クラスでメソッドをデバッグしたかったのですが、その方法Update-Databaseがわかりませんでした。他の人が同じ問題を抱えている場合に備えて、解決策を他の人と共有したかったのです。

4

7 に答える 7

168

これは、非常にうまく機能するソリューションを備えた同様の質問です。
必要ありませんThread.Sleep
このコードを使用してデバッガーを起動します。

答えから切り取った

if (!System.Diagnostics.Debugger.IsAttached) 
    System.Diagnostics.Debugger.Launch();
于 2013-08-12T15:23:49.883 に答える
20

これを解決する方法は、Visual Studio の新しいインスタンスを開き、この Visual Studio の新しいインスタンスで同じソリューションを開くことでした。次に、update-database コマンドの実行中に、この新しいインスタンスのデバッガーを古いインスタンス (devenv.exe) にアタッチしました。これにより、シード メソッドをデバッグできました。

時間内にアタッチしないことでブレークポイントを見逃さないようにするために、ブレークポイントの前に Thread.Sleep を追加しました。

これが誰かに役立つことを願っています。

于 2013-05-23T15:52:44.317 に答える
14

特定の変数の値を取得する必要がある場合、簡単なハックは例外をスローすることです。

throw new Exception(variable);
于 2013-11-21T14:13:57.747 に答える
3

これは古い質問だと思いますが、メッセージだけが必要で、プロジェクトに WinForms への参照を含めたくない場合は、Trace イベントを送信できる簡単なデバッグ ウィンドウをいくつか作成しました。

より本格的で段階的なデバッグを行うために、別の 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);
    }
  }
}

そして、標準の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!")
      // ...
    }
  }
}
于 2014-11-03T06:45:29.183 に答える