ডিবাগিং প্যাকেজ ম্যানেজার কনসোল আপডেট-ডাটাবেস বীজ পদ্ধতি


106

আমি Seed()যখন Update-Databaseপ্যাকেজ ম্যানেজার কনসোল থেকে রান করি তখন আমি আমার সত্তা ফ্রেমওয়ার্ক ডাটাবেস কনফিগারেশন ক্লাসে পদ্ধতিটি ডিবাগ করতে চেয়েছিলাম কিন্তু কীভাবে এটি করতে হয় তা জানতাম না। অন্যদের যদি একই সমস্যা হয় তবে আমি সমাধানটি ভাগ করে নিতে চাই।

উত্তর:


158

এখানে একটি সমাধানের সাথে একই রকম প্রশ্ন যা সত্যিই ভালভাবে কাজ করে।
এটি প্রয়োজন হয় না Thread.Sleep
কেবল এই কোডটি ব্যবহার করে ডিবাগারটি চালু করে।

উত্তর থেকে ক্লিপড

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

@ চেইলিডজে আপনি migrate.exeবর্তমানে চলমান ভিজ্যুয়াল স্টুডিও সংযুক্ত করতে কনসোল থেকে কল করতে পারেন । এই উত্তরটি আরও তথ্য: stackoverflow.com/a/52700520/350384
Mariusz Pawelski

20

আমি যেভাবে সমাধান করেছি তা হ'ল ভিজুয়াল স্টুডিওর একটি নতুন উদাহরণ খুলুন এবং তারপরে ভিজুয়াল স্টুডিওর এই নতুন উদাহরণটিতে একই সমাধানটি খুলুন। আমি আপডেট-ডাটাবেস কমান্ডটি চালনার সময় এই নতুন উদাহরণটিতে ডিবাগারটিকে পুরানো উদাহরণ (devenv.exe) এর সাথে সংযুক্ত করেছিলাম। এটি আমাকে বীজ পদ্ধতিটি ডিবাগ করার অনুমতি দেয়।

ঠিক সময়ে এটি সংযুক্ত না করে ব্রেকপয়েন্টটি মিস করেছি তা নিশ্চিত করার জন্য আমি একটি থ্রেড যুক্ত করেছি। ব্রেকপয়েন্টের আগে ঘুমাও।

আমি আশা করি এটা কারো সাহায্যে লাগবে.


12

যদি আপনাকে একটি নির্দিষ্ট ভেরিয়েবলের মান পেতে হয় তবে একটি দ্রুত হ্যাক একটি ব্যতিক্রম ছোঁড়াতে হবে:

throw new Exception(variable);

3
দ্রুত এবং মলিন :)
ডানকোডি

5

একটি ক্লিনার সমাধান (আমার ধারণা এটির জন্য এএফ 6 প্রয়োজন) আইএমএইচও কোড থেকে আপডেট-ডাটাবেস কল করবে:

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

এটি আপনাকে বীজ পদ্ধতিটি ডিবাগ করতে দেয়।

আপনি এটি আরও একধাপ এগিয়ে নিয়ে যেতে পারেন এবং একটি ইউনিট পরীক্ষা নির্মাণ করতে পারেন (বা আরও সুনির্দিষ্টভাবে একটি ইন্টিগ্রেশন টেস্ট) যা খালি পরীক্ষার ডাটাবেস তৈরি করে, সমস্ত EF মাইগ্রেশন প্রয়োগ করে, বীজ পদ্ধতি চালায় এবং পরীক্ষার ডাটাবেসটি আবার ড্রপ করে:

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

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

Database.Delete("TestDatabaseNameOrConnectionString");

তবে আপনার বিকাশের ডাটাবেসের বিরুদ্ধে এটি চালাতে সাবধান হন!


1
EF কোরে যেহেতু কোনও DbMigrationsConfigration ক্লাস নেই তার পরিবর্তে myDbContext.Database.GetPendMigration () ব্যবহার করুন।
স্টিভি_সি

3

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আপনি যদি চান সমস্ত বার্তা হ'ল এবং আপনার প্রকল্পে উইনফোর্ডসের উল্লেখগুলি অন্তর্ভুক্ত করার বিষয়ে চিন্তা করবেন না, আমি কিছু সাধারণ ডিবাগ উইন্ডো তৈরি করেছি যেখানে আমি ট্রেস ইভেন্টগুলি পাঠাতে পারি।

আরও গুরুতর এবং ধাপে ধাপে ডিবাগিংয়ের জন্য, আমি আরেকটি ভিজ্যুয়াল স্টুডিও উদাহরণ খুলব, তবে সাধারণ স্টাফের জন্য এটি প্রয়োজনীয় নয়।

এটি পুরো কোড:

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

এবং আপনার স্ট্যান্ডার্ড কনফিগারেশন। সি

// ...
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
অবশ্যই, ডিবাগ উইন্ডোটি আপনার পছন্দ মতো জটিল হতে পারে (আপনি এমনকি ডিজাইনারটিকে একটি সম্পূর্ণ ফর্ম তৈরি করতে এবং এটি পাশ দিয়ে পাস SeedInternalকরতে পারেন যাতে পদ্ধতিটি এটি ব্যবহার করতে পারে)
Jcl

1

উহ ডিবাগিং হ'ল একটি জিনিস তবে কল করতে ভুলবেন না: প্রসঙ্গ। আপডেট ()

কনসোলে কোনও ভাল অভ্যন্তরীণ ব্যতিক্রম ছড়িয়ে না দিয়ে ক্যাপচার চেষ্টা করে মোড়ানোও হবে না।
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code- প্রথম ধরা সহ (DbEntityValidationException প্রাক্তন)


দয়া করে এই ইউআরএলটি পরীক্ষা করুন এটি আপনার সামগ্রীর গুণমানকে উপরে তুলতে কার্যকর হবে
উইলি চেং

0

আমার 2 টি Debugger.Launch()কার্যকার্য রয়েছে ( যেহেতু এটি আমার পক্ষে কাজ করে না):

  1. প্যাকেজ ম্যানেজার কনসোলে বার্তা প্রিন্ট করতে ব্যতিক্রমটি ব্যবহার করুন:
    throw new Exception("Your message");

  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);
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.