답변:
더 깨끗한 솔루션 (EF 6이 필요하다고 생각합니다)은 IMHO가 코드에서 update-database를 호출하는 것입니다.
var configuration = new DbMigrationsConfiguration<TContext>();
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
이렇게하면 Seed 메서드를 디버깅 할 수 있습니다.
한 단계 더 나아가 빈 테스트 데이터베이스를 만들고, 모든 EF 마이그레이션을 적용하고, Seed 메서드를 실행하고, 테스트 데이터베이스를 다시 삭제하는 단위 테스트 (또는 더 정확하게는 통합 테스트)를 구성 할 수 있습니다.
var configuration = new DbMigrationsConfiguration<TContext>();
Database.Delete("TestDatabaseNameOrConnectionString");
var databaseMigrator = new DbMigrator(configuration);
databaseMigrator.Update();
Database.Delete("TestDatabaseNameOrConnectionString");
그러나 개발 데이터베이스에 대해 실행하지 않도록주의하십시오!
이것이 오래된 질문이라는 것을 알고 있지만 원하는 것이 메시지 뿐이고 프로젝트에 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!")
// ...
}
}
}
SeedInternal
메서드에서 사용할 수 있음)
Uh 디버깅은 한 가지이지만 context.Update () 호출하는 것을 잊지 마십시오.
또한 내부 예외가 콘솔에 쏟아지지 않고 try catch로 래핑하지 마십시오.
https://coderwall.com/p/fbcyaw/debug-into-entity-framework-code-first
with catch (DbEntityValidationException ex)
두 가지 해결 방법이 있습니다 ( Debugger.Launch()
나에게 적합하지 않기 때문에).
패키지 관리자 콘솔에서 메시지를 인쇄하려면 예외를 사용하십시오.
throw new Exception("Your message");
또 다른 방법은 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);
}
migrate.exe
는 콘솔에서 호출 하여 현재 실행중인 Visual Studio를 연결할 수 있습니다 . 이 답변에 대한 추가 정보를 원하시면 : stackoverflow.com/a/52700520/350384