数据库类实例,字段,实体框架

问题描述:

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

你是在你的描述有点不准确的。这归因于你的困惑。

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

非常感谢您的广泛反思和错误发现!我将与代码的作者谈谈,以了解真正发生的事情 –