Debugging Package Manager Console Метад Seed Update-Database

Я хацеў, каб адладзіць метад Seed() у маім класе канфігурацыі базы дадзеных Entity Framework пры запуску абнаўлення-баз дадзеных з пакета кансолі дыспетчара, але не ведалі, як гэта зрабіць. Я хацеў бы падзяліцца рашэннем з іншымі ў выпадку, калі яны маюць адзін і той жа пытанне.

95

7 адказы

Here is similar question with a solution that works really well.
It does NOT require Thread.Sleep.
Just Launches the debugger using this code.

Абрэзаныя ад адказу

if (!System.Diagnostics.Debugger.IsAttached) 
    System.Diagnostics.Debugger.Launch();
136
дададзена
Я выкарыстаў гэты метад, і ён выдатна працуе.
дададзена аўтар Chris Pickford, крыніца
працуе, але і адкрывае новыя візуальныя студыі.
дададзена аўтар tchelidze, крыніца

Так я вырашыў гэта было адкрыць новы асобнік Visual Studio, а затым адкрыць такое ж рашэнне ў гэтым новым экзэмпляры Visual Studio. Затым я прымацаваў адладчык ў гэтым новым экзэмпляры для старога асобніка (devenv.exe) пры выкананні каманды абнаўлення-базах дадзеных. Гэта дазволіла мне адладжваць метад Seed.

Проста каб пераканацца, што я не прапусціў кантрольную кропку, ня прымацаванне часу я дадаў Thread.Sleep да кропкі супыну.

Я спадзяюся, што гэта дапаможа камусьці.

17
дададзена
Дзякуй, гэта спрацавала для мяне.
дададзена аўтар VivekDev, крыніца

Калі вам трэба атрымаць значэнне канкрэтнай зменнай, хуткі хак кінуць выключэнне:

throw new Exception(variable);
8
дададзена
Хуткая і брудная :)
дададзена аўтар DanKodi, крыніца

Прыбіральнік рашэнне (я мяркую, што гэта патрабуе EF 6) будзе IMHO будзе выклікаць абнаўленне-базы дадзеных з кода:

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

Гэта дазваляе адладжваць метад насення.

Вы можаце зрабіць яшчэ адзін крок і пабудаваць модульны тэст (ці, дакладней, інтэграцыйны тэст), які стварае пустыя тэставую базу дадзеных, прымяняе ўсе EF міграцыю, запускае метад насення, і зноў падае тэставую базу дадзеных:

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

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

Database.Delete("TestDatabaseNameOrConnectionString");

Але будзьце асцярожныя, каб не запускаць гэта супраць вашай базы дадзеных распрацоўкі!

3
дададзена
У EF стрыжні, бо няма выкарыстоўваць клас DbMigrationsConfiguration myDbContext.Database.GetPendingMigrations() замест гэтага.
дададзена аўтар stevie_c, крыніца

Я ведаю, што гэта стары пытанне, але калі ўсё, што вы хочаце, гэта паведамленне, і вы не клапоціцеся ўключаць спасылкі на WinForms ў вашым праекце, я зрабіў некалькі просты адладку вокны, дзе я магу адправіць трасіроўкі падзея.

Для больш сур'ёзнага і крок за крокам адладкі, я адкрыю яшчэ адзін асобнік Візуальная студыі, але гэта не абавязкова для простых рэчаў.

Гэта ўвесь код:

<�Моцны> 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 : ApplicationContext
    where T : DbContext
  {
    private class SeedTraceListener : TraceListener
    {
      private readonly SeedApplicationContext _appContext;

      public SeedTraceListener(SeedApplicationContext 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 _seedAction;
    private readonly T _dbcontext;

    public Exception Exception { get; private set; }
    public bool WaitBeforeExit { get; private set; }

    public SeedApplicationContext(Action 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);
    }
  }
}

And on your standard Configuration.cs

// ...
using System.Windows.Forms;
using Data.Persistence.Migrations.SeedDebug;
// ...

namespace Data.Persistence.Migrations
{
  internal sealed class Configuration : DbMigrationsConfiguration
  {
    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(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!")
     //...
    }
  }
}
2
дададзена
Вядома, акно адладкі можа быць гэтак жа складаным, як вы хочаце (вы можаце нават выкарыстоўваць канструктар, каб стварыць поўную форму і перадаць яго вакол, так што SeedInternal метад можа выкарыстоўваць)
дададзена аўтар Jcl, крыніца

Мм Debugging гэта адно, але не забудзьцеся патэлефанаваць: context.Update ()

Таксама не загарнуць у спробе злавіць без добрых ўнутраных выключэнняў праліваць на кансоль.
https://coderwall.com/p/fbcyaw/debug-into -логический аб'ект-рамка-кода першага з уловам (DbEntityValidationException ех)

1
дададзена
Калі ласка, праверце гэтую URL гэта будзе карысна, каб падняць ваша якасць кантэнту да
дададзена аўтар Willie Cheng, крыніца

У мяне ёсць 2 абыходныя шляхі (без Debugger.Launch() , так як ён не працуе для мяне):

  1. Для таго, каб раздрукаваць паведамленне ў Package Manager Console выкарыстоўваць выключэнне:
    <�Код> праліваюць новы Exception ( "Ваша паведамленне");

  2. Іншы спосаб надрукаваць паведамленне ў файле шляхам стварэння 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);
    }
0
дададзена