2017-08-09 50 views
0

Im新的C#和實體框架,我有一個關於數據庫類的字段和初始化的問題。數據庫類實例,字段,實體框架

我從我的老師的程序中收到了一些通過實體框架與MySQL數據庫連接的代碼。

到目前爲止,我們已經看到了一些示例,其中用於向數據庫添加東西的內部方法首先創建它的一個實例。我們迄今爲止看到的一個例子:

using (var db = new p4_databaseEntities()) 
     { 
      cp_car carEntity = new cp_car(); 
      carEntity.make = car.make; 
      carEntity.model = car.model; 
      carEntity.year = car.year; 

      db.cp_car.Add(carEntity); // 
      db.SaveChanges(); 

      MessageBox.Show("A Car has been added"); 

     } 
     this.Close(); 

cp_car是數據庫中的表和程序中的類。 db是數據庫的當前實例。

現在,在我收到的代碼中,這不是這樣完成的。它在另一個問題上完成。順便說一句,該方案是一個Windows窗體。

在構造函數的第一個窗體窗口中,他創建了一個新的數據庫實例,並從另一個名爲LinqQueries的類中調用名爲init 的方法。該代碼:

public Form1() 
    { 
     InitializeComponent(); 


     p4_databaseEntities db = new p4_databaseEntities(); 
     LinqQueries.Init(db); 

     this.CenterToScreen(); 
    } 

如何LinqQueries類如下:

 private static p4_databaseEntities _db; 

    public static void Init(p4_databaseEntities db) 
    { 
     _db = db; 
    } 

據我瞭解,他在構造函數中,在那裏他還呼籲init方法創建的數據庫的一個新實例。此方法然後將db對象定義爲_db。現在他爲從數據庫中添加或刪除數據所使用的每一種方法都使用_db而不是db。

我的問題是,這是否意味着init方法將類型爲p4_databaseEntities(數據庫類的名稱)的靜態字段指定爲對象? _db然後是一個對象的值?它是一個對象的引用嗎?同時我也注意到,在對數據庫進行更改時,他一次又一次地使用相同的字段,導致我相信它可能是一個活動對象,它不會在程序壽命中死去?

如果有人可以澄清這將不勝感激。請原諒我所做的任何錯誤或錯誤陳述,如有任何形式的錯誤,請糾正我。我是C#和實體框架的新成員。

由於事先

+0

誰寫的代碼?你可以問作者嗎? – mjwills

回答

0

你是在你的描述有點不準確的。這歸因於你的困惑。

DbContext不是數據庫,它表示到數據庫的連接。如果構建DbContext對象,則可以通過DbSet中描述的實體訪問數據庫中的表。

儘管看起來DbSet代表數據庫中的一個表,但它沒有。例如,通過DbSet訪問的實體可以擁有一個ICollection作爲成員,其中包含不屬於表的項目,但是是不同表格中的項目。訪問此ICollection中的項會導致執行SQL連接,而無需鍵入連接

因此,DbConnection中的DbSet對象不表示數據庫表,它表示對可以使用的屬性進行訪問DbSet對象,包括數據庫中與DbSet對象具有關係的表中的所有對象的屬性。

你的第一個使用using語句的代碼是應該使用正常方式的實體框架。

要隱藏數據庫的設計,通常會引入一個獨立的類,它是唯一應該使用DbContext的類。數據庫的所有用戶應該使用單獨的類進行通信。

這允許更改數據庫的內部,而無需更改使用數據庫的代碼。

這可能是LinqQueries類的目的。用戶應該直接調用LinqQueries的(可能是靜態的)函數,而不是直接調用DbContext的函數。這樣,數據庫的內部結構就可以改變,而不必改變LinqQueries函數的調用者。

實際上發生的事情是LinqQueries只能與一個DbContext進行通信。 LinqQueries不決定使用哪個DbContext。恰當的功能在很大程度上取決於LinqQueries的一個用戶,他們應該創建一個DbContext和Init LinqQueries。這個用戶也應該知道什麼時候沒有人需要LinqQueries,因爲他必須Dispose()DbContext。

這個設計很容易出錯。假設設計師製造出非常優秀的產品,他的產品將被許多用戶(即軟件,而不是運營商)使用。你如何斷言只有一個用戶會調用Init函數?

如果您確實希望所有用戶使用相同的Dbcontext,爲什麼不讓LinqQueries的構造函數創建此DbContext。事實上,該設計與單例設計模式類似,所以爲什麼不將LinqQueries創建爲單例模式。

LinqQuery的所有用戶都應該使用相同的限制,並且只有DbContext限制不必要地使用LinqQuery類。

如果LinqQuery類的用戶可以將DbContext傳遞給構造函數,那麼用戶可以決定該特定LinqQueries對象應該使用哪個數據庫。這在創建單元測試時非常方便:不使用原始數據庫,可測試代碼可以與具有特定測試值的數據庫一起使用。

設計師的所有目標都不清楚。恕我直言,這是一個糟糕的設計,你是對的,它不清楚會發生什麼。

class LinqQueries 
{ 
    // default constructor: use the default DbContext 
    public LinqQueries() 
    { 
     this.DbContext = new p4_databaseEntities(); 
    } 

    // special constructor: user provided dbContext 
    public LinqQueries(p4_databaseEntities dbContext) 
    { 
     this.dbContext = dbContext; 
    } 

    private readonly p4_databaseEntities dbContext; 

    public IEnumerable<...> GetMyElements(...) 
    { 
     return this.dbContext....; 
    } 
} 

這樣,LinqQueries的每一個創作者會確切地知道該怎麼做既可以使用默認的p4_databaseEntities或創建自己的DbContext和處置它時,不再

using (var mydbContext = new p4_databaseEntities()) 
{ 
    LinqQueries linqQueries = new LinqQueries(myDbContext); 
    // note that this constructor is very lightWeight! 

    var result = linqQueries.MyQeury(...); 
} 

需要這個方法是很安全。我所做的任何錯誤都不會影響LinqQuery類的任何其他用戶的代碼。

+0

非常感謝您的廣泛反思和錯誤發現!我將與代碼的作者談談,以瞭解真正發生的事情 –