2017-06-30 37 views
-1

我有一個LogContext型號:麻煩連接到我的實體框架C#的Web API數據庫

using System.Data.Entity; 

namespace Logging.Models 
{ 
    public class LogContext : DbContext 
    { 
     // You can add custom code to this file. Changes will not be overwritten. 
     // 
     // If you want Entity Framework to drop and regenerate your database 
     // automatically whenever you change your model schema, add the following 
     // code to the Application_Start method in your Global.asax file. 
     // Note: this will destroy and re-create your database with every model change. 
     // 
     // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<Logging.Models.ProductContext>()); 

     public LogContext() : base("name=LogContext") 
     { 
      Database.SetInitializer<LogContext>(null); 
     } 

     public DbSet<Log> Logs { get; set; } 




    } 
} 

但是當我嘗試引用的日誌我在其他LogContext類的app_code下我得到想要的錯誤引用context.Logs.Load(); 「 」不能通過實例引用進行訪問;使用類型名稱對其進行限定「

如何引用和呈現表中的所有行?我究竟做錯了什麼? 謝謝

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Logging.Controllers; 
using Logging.Models; 

namespace Logging 
{ 
    public class LogContext : IDisposable 
    { 
     private static readonly List<Log> Logs = new List<Log>(); 

     static LogContext() 
     { 
      using (var context = new LogContext()) 
      { 
       **context.Logs.Load();** 
      } 
      //Logs.Add(new Log() { Id = 1, LoggerName = "TESTSYS1", InnerException = "InnerException", LogText = "LogText", ThreadID = 1, StackTrace = "Stack Trace", eLevel = "INFO" }); 
      //Logs.Add(new Log() { Id = 2, LoggerName = "TESTSYS2", InnerException = "InnerException", LogText = "LogText", ThreadID = 2, StackTrace = "Stack Trace", eLevel = "ERROR" }); 
      //Logs.Add(new Log() { Id = 3, LoggerName = "TESTSYS3", InnerException = "InnerException", LogText = "LogText", ThreadID = 3, StackTrace = "Stack Trace", eLevel = "WARN" }); 
     } 
     void IDisposable.Dispose() 
     { 

     } 


     public void GetLoggies() 
     { 
      using (var context = new LogContext()) 
      { 
       foreach (var log in context.GetLogs()) 
       { 
        Logs.Add(log); 

       } 
      } 
     } 

     public Log GetLog(int id) 
     { 
      var log = Logs.Find(p => p.Id == id); 
      return log; 
     } 

     public IEnumerable<Log> GetLogs() 
     { 
      return LogContext.Logs; 
     } 

     public Log AddLog(Log p) 
     { 
      Logs.Add(p); 
      return p; 
     } 

     public void Delete(int id) 
     { 
      var product = Logs.FirstOrDefault(p => p.Id == id); 
      if (product != null) 
      { 
       Logs.Remove(product); 
      } 
     } 

     public bool Update(int id, Log log) 
     { 
      Log rLog = Logs.FirstOrDefault(p => p.Id == id); 
      if (rLog != null) 
      { 
       rLog = log; 
       return true; 
      } 
      return false; 
     } 
    } 
} 

回答

3

問題是坦率的非常糟糕的設計。這裏

  1. 你的類具有相同的名稱爲您的上下文,也有相同的名稱作爲您的上下文的成員,即Logs成員。這是一個關於編譯器有多聰明的案例研究,因爲整個事件不會爆炸的唯一原因是因爲它能夠在給定上下文的情況下在哪個位置使用某種意義。不過,它可能會猜錯,並且肯定會在某些時候感到困惑。如果你堅持這樣維護它,你應該完全限定你的實際上下文類的所有用途,即new Namespace.To.LogContext(),所以編譯器不只是猜測。

  2. 使用using圍繞上下文是巨大壞主意。上下文實例最好是請求範圍。除此之外,上下文采用了變更跟蹤,並且當您開始在不同的上下文實例之間傳遞實體時,您將一頭扎進磚牆。相反,你應該注入你的上下文到這個類中,並把它作爲一個字段保存在類中。

  3. 實施IDisposable不是你應該輕易做的事情。有一個非常特殊的方式需要實施,或者你實際上造成的傷害遠遠超過了好處。

    public class Base: IDisposable 
    { 
        private bool disposed = false; 
    
        //Implement IDisposable. 
        public void Dispose() 
        { 
         Dispose(true); 
         GC.SuppressFinalize(this); 
        } 
    
        protected virtual void Dispose(bool disposing) 
        { 
         if (!disposed) 
         { 
          if (disposing) 
          { 
           // Free other state (managed objects). 
          } 
          // Free your own state (unmanaged objects). 
          // Set large fields to null. 
          disposed = true; 
         } 
        } 
    
        // Use C# destructor syntax for finalization code. 
        ~Base() 
        { 
         // Simply call Dispose(false). 
         Dispose (false); 
        } 
    } 
    

    參見:https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx

    但是,如果你注入你的背景下,這一類將不再擁有的背景下,因此不會需要甚至實現IDisposable。而且,對於一切美好和聖潔的愛,不要在注入依賴時實現IDisposable。我看到太多的開發人員會這樣做,最終會出現一些奇怪的錯誤,因爲資源配置不正確。

  4. 最後,完全拋棄這門課。你在本質上試圖在這裏創建的(不正確的)是一個存儲庫,而你並不需要它。實體框架已經實現了存儲庫和工作模式單元。正如你在這裏看到的那樣,你所做的只是從你的方法代理到DbSet上幾乎相同的方法。你自己什麼都不買,只是現在必須維護的一個額外的層,更多的熵你的應用程序代碼和技術債務。對於爲什麼這是一個更詳細的描述錯誤的做法,請參閱:https://softwareengineering.stackexchange.com/a/220126/65618

+0

好,我扔掉的app_code下LogContext類,和我再生從控制器的方法,現在我有模式下只有一個LogContext類有看起來像這樣的方法:\t \t 內部日誌GetLog(INT ID) \t \t { \t \t \t拋出新NotImplementedException(); \t \t} – Lyle

+0

如何「注入」我的上下文? – Lyle

+0

不要告訴我我正在做的一切都是廢話,然後離開我沒有解決方案 – Lyle