2011-12-26 46 views
4

我想用SQLCE4數據庫的實體框架代碼第一種方法。一切似乎都非常好,但我有調試SQL查詢的問題。我發現從http://efwrappers.codeplex.com/ EFTracing應該是我所需要的,但我不知道如何使用它沒有app.config文件。我不是這個配置的大粉絲。我只想用C#代碼來設置和運行所有的東西。我認爲應該可以使用這樣的代碼:實體框架無配置文件的跟蹤提供者包裝

using (System.Data.Common.DbConnection c = 
    new EFTracingProvider.EFTracingConnection(
     new System.Data.SqlServerCe.SqlCeConnection(conn))) 
{ 
    using (var context = new MyContext(c)) 
    { 
     var a = from data in context.Projects select data; 
    } 
} 

但它不起作用。它會拋出異常:

無法確定連接類型爲 的EFTracingProvider.EFTracingConnection的提供程序名稱。

有沒有簡單的方法如何正確創建包裝連接只在代碼中?

回答

6

解決我的問題是下面的DbContext對象。

public class MyContext : DbContext 
{ 
    public MyContext() 
    : base(CreateConnection("Data Source=file.sdf", 
          "System.Data.SqlServerCe.4.0"), true) 
    { } 

    public DbSet<Project> Projects { get; set; } 

    public static bool TraceEnabled = true; 

    private static DbConnection CreateConnection(string connectionString, 
               string providerInvariantName) 
    { 
    DbConnection connection = null; 
    if (TraceEnabled) 
    { 
     EFTracingProviderConfiguration.RegisterProvider(); 
     EFTracingProviderConfiguration.LogToConsole = true; 
     string wrapperConnectionString = String.Format(@"wrappedProvider={0};{1}", 
     providerInvariantName, connectionString); 
     connection = new EFTracingConnection() 
     { 
     ConnectionString = wrapperConnectionString 
     }; 
    } 
    else 
    { 
     DbProviderFactory factory = DbProviderFactories.GetFactory(providerInvariantName); 
     connection = factory.CreateConnection(); 
     connection.ConnectionString = connectionString; 
    } 
    return connection; 
    } 
} 

所以,現在我可以只使用環境和連接是根據TraceEnabled財產包裹或未包裹SQLCE自動創建。

using (var context = new MyContext()) 
{ 
    var a = context.Projects.FirstOrDefault(); 
} 
+0

這似乎不適用於它的遷移部分。我正在尋找解決方案。 – aikeru 2013-08-16 16:37:24

0

的真正的方法來跟蹤SQL查詢是調用ToString方法類似:

var t = from c in _entities.CompanyDetail 
     select c; 

string test = t.ToString(); 

我不知道EFTracing,但你可能想嘗試MVCMiniProfiler。儘管名稱MVCMiniProfiler也提供了SQL查詢分析和工作沒有配置文件。

+0

對不起,編輯不好,我從我的手機回答。感謝Uwe keim尋求幫助 – 2011-12-26 15:44:02

+0

感謝MVCMiniProfiler。這可能是非常有用的。 – 2011-12-27 19:23:29

0

我已經通過圍繞ObjectContext創建包裝類並使用該包裝代替原始上下文來完成此操作。下面是一個例子上下文包裝:

public partial class LoggedContext : MyContext 
{ 
    public LoggedContext() 
     : this("name=MyEntities") // Adjust this to match your entities 
    { 
    } 

    public LoggedContext(string connectionString) 
     : base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(connectionString) 
    { 
    } 

    private EFTracingConnection TracingConnection 
    { 
     get { return this.UnwrapConnection<EFTracingConnection>(); } 
    } 

    public event EventHandler<CommandExecutionEventArgs> CommandExecuting 
    { 
     add { this.TracingConnection.CommandExecuting += value; } 
     remove { this.TracingConnection.CommandExecuting -= value; } 
    } 

    public event EventHandler<CommandExecutionEventArgs> CommandFinished 
    { 
     add { this.TracingConnection.CommandFinished += value; } 
     remove { this.TracingConnection.CommandFinished -= value; } 
    } 

    public event EventHandler<CommandExecutionEventArgs> CommandFailed 
    { 
     add { this.TracingConnection.CommandFailed += value; } 
     remove { this.TracingConnection.CommandFailed -= value; } 
    } 
} 

我也有限定跟蹤輸出方法,並具有一個靜態方法來初始化跟蹤一個靜態類。這裏:

public static class EFTracingExtensions 
{ 
    private static ILogger _logger; 

    public static void InitSqlTracing(ILogger logger) 
    { 
     _logger = logger; 

     EFTracingProviderConfiguration.RegisterProvider(); 

     if (logger.IsLoggingEnabled())   // Don't add logging hooks if logging isn't enabled 
     { 
      EFTracingProviderConfiguration.LogAction = new Action<CommandExecutionEventArgs>(AppendSqlLog); 
     } 
    } 

    private static void AppendSqlLog(CommandExecutionEventArgs e) 
    { 
     if (e.Status != CommandExecutionStatus.Executing)    // we only care about Finished and Failed 
     { 
      StringBuilder msg = new StringBuilder(e.ToTraceString().TrimEnd()); 
      msg.Append(Environment.NewLine); 
      if (e.Result is SqlDataReader) 
      { 
       int rows = ((SqlDataReader)e.Result).HasRows ? ((SqlDataReader)e.Result).RecordsAffected : 0; 
       msg.AppendFormat("*** {0} rows affected", rows); 
      } 
      else if (e.Result is int) 
      { 
       msg.AppendFormat("*** result: {0}", e.Result); 
      } 
      else 
      { 
       msg.AppendFormat("*** finished, result: {0}", e.Result); 
      } 

      msg.Append(Environment.NewLine); 
      msg.AppendFormat(" [{0}] [{1}] in {2} seconds", e.Method, e.Status, e.Duration); 
      _logger.Log(msg.ToString(), LoggerCategories.SQL); 
     } 
    } 
} 

ILogger是我正在使用的日誌記錄界面。你需要替換你自己的接口/方法。

當我的程序啓動時,InitSqlTracing方法被調用一次,然後使用LoggedContext類記錄Entity Framework生成的所有SQL。

與示例代碼全部放在一起:

EFTracingExtensions.InitSqlTracing(logger); // only call this once 

using (var context = new LoggedContext()) 
{ 
    var a = from data in context.Projects select data; 
} 
+0

我使用代碼優先的方法,所以有DbContext而不是ObjectContext,所以我需要一些不同的東西。 – 2011-12-27 19:25:13