• 实体框架Entity Framework 4.1快速入门


      随着.NET 4.0时代的到来,开发者越来越关注如何能加快开发效率,从而构建健壮的程序。而微软在.NET 4.0推出的Entity Framework,无疑是值得开发者去学习的,它实际上是微软的ADO.NET的增强版本,是个ORM框架。在本文中,将以例子的形式简单介绍最新的Entity Framework 4.1的基本用法。

      介 绍

      在旧的Entity 框架中,开发者可以从已存在的数据库中产生业务实体的模型,这种开发方法被称为数据库驱动的开发方法。而在4.1的Entity Framework中,支开发者先创建实体业务类,然后再产生相关的数据库文件,这种开发方法可以称为“代码先行”的开发方法。这种方法对于开发者来说是很有好处的,首先,会让开发者从面向对象的思维角度出发,去构建业务逻辑中的实体模型,然后再根据实际的需要去生成数据库文件,是真正的面向对象的思维开发方法。

      本文中要使用Entity Framework 4.1,这里提供下载该框架安装程序:Entity Framework 4.1

      同时,VS.NET 2010也是少不了的,而本文的配套代码,可以在这里下载:VS.NET 2010

      本文的例子将会创建两个类Invoice类和LineItem类。而本文产生的数据库命名为Accounting,并会产生两张表:Invoice和LineItem。例子中的功能,还包括可以在gridview中对数据库中的数据进行增删改查,最后,还会演示如果类发生了变化了,如何让相应的数据库也发生改变。

      步骤1

      1) 启动vs.net 2010;

      2) 新建立一个c#语言的asp.net web工程项目;

      3) 将工程命名为project EF4CodeFirst;

      4) 在工程资源管理器中,鼠标右键点击,然后新增一个类,将新增的类命名为Invoice.cs。

      修改这个类的代码如下:

      public class Invoice
    {
        public int ID { getset; }
        public DateTime InvoiceDate { getset; }
        public double Total { getset; }
    }

      在我们的类中,有id这个属性,Entity框架会根据id这个属性,去生成数据库表中的对应字段id,如果类中没定义id这个属性,则会在数据库表文件中生成以“类文件名+ID”这样命名的字段。

      在这个Invoice发票类中,存在多个条目LineItem,它们之间明显构成一对多的关系,所以我们先建立类LineItem类。

      5) 同样,新增一个LineItem类,代码如下:

       public class LineItem
    {
        public int ID { getset; }
        public string ProductName { getset; }
        public double ItemCost { getset; }
        public double Units { getset; }
        public Invoice Invoice { getset; }
    }

      在这个类中,维持了对Invoice类的引用,同时也是关联了Invoice类。

      6)而在Invoice类中,也要增加LineItem类的引用,这里要用到的是集合类,如下代码:

       public ICollection<LineItem> LineItems { getset; }

      同时要在Invovice类的构造函数中,进行初始化LineItem类,如下:

    public Invoice()
    {
        LineItems = new List<LineItem>();
    }

      在完成上面的步骤后,则Entity框架已可以从实体类中创建相关的数据库和表了,下面继续进行步骤二。


      步骤2

      接下来,我们要引用Entity框架的类库文件到我们的工程中。

      1) 在工程资源管理器中,鼠标右键点击工程名字,在弹出的菜单中选择“添加引用”。

      2) 在出现的如下图的界面中,选择System.Data.Entity ,并点确定完成:

      3) 为工程继续增加一个新类,命名为Accounting.cs ,并且修改其代码如下:

    using System.Data.Entity;
    public class Accounting : DbContext
    {
    public DbSet<Invoice> Invoices { getset; }
    public DbSet<LineItem> LineItems { getset; }
    }

      可以看到,该类继承了DbContext类,该类实际上是Entity的一个工具类,里面封装了很多有用的API,在Accounting类中,分别有两个DbSet类的实例,它们代表将要在数据库中生成的两个表。

      4)接着需要在web.config中进行添加数据库连接,如下:

    <add name="Accounting" 
    providerName="System.Data.SqlClient" 
    connectionString="Data Source=(local);Initial Catalog=Accounting;Integrated Security=SSPI;"/>

      5) 接着,在default.aspx 中添加gridview控件,并且编写如下代码:

    using System.Data.Entity;
    protected void Page_Load(object sender, EventArgs e)
    {
    Accounting db = new Accounting();
    db.Invoices.Load();
    GridView1.DataSource = db.Invoices.Local.ToBindingList();
    GridView1.DataBind();
    }

      记得这里必须引入System.Data.Entity类库,并且实例化Accounting对象的实例db,并调用其load方法,加载所有的Invoice数据(这里我们一般是加载一对多的一方的数据)。


      6)运行工程后,你会发现在SQL SERVER中,会出现了三张表,如下图:

      其中,分别是Invoice表和LineItem表,还有一张表EdmMetadata,是Entity框架为我们自动生成的,保存了数据库中的元数据。另外,可以看到在表LineItem中,Entity框架已经为我们自动生成了外键Invoice_ID,如下图:

      步骤三

      现在,既然数据库已经创建了,则可以为其增加一些数据了,在page_load中增加如下代码:

    protected void Page_Load(object sender, EventArgs e)
    {
    Accounting db = new Accounting();
    Invoice invoice = new Invoice
    {
    InvoiceDate = DateTime.Now,
    Total = 1000
    };
    db.Invoices.Add(invoice);
    db.SaveChanges();
    db.Invoices.Load();
    GridView1.DataSource = db.Invoices.Local.ToBindingList();
    GridView1.DataBind();
    }

      在这里我们实例化了Invoice类的一个实例,添加了相关的数据内容,然后使用db.Invoices.Add增加到Account类的DBSet属性中,最后调用savechanges方法保存到数据库中,运行后,可以看到如下效果:

      现在我们试下更新数据,代码如下:

    protected void Page_Load(object sender, EventArgs e)
    {
    Accounting db = new Accounting();
    Invoice invoice = new Invoice
    {
    ID = 1,
    InvoiceDate = DateTime.Now,
    Total = 900
    };
    db.Entry(invoice).State = EntityState.Modified;
    db.SaveChanges();
    db.Invoices.Load();
    GridView1.DataSource = db.Invoices.Local.ToBindingList();
    GridView1.DataBind();
    }

      这里把invoice实例的成员变量的ID改为1,注意在更新时,设置其状态(state)为EntityState.Modified,表示是修改记录,最后再保存,运行后,可以看到数据库中的数据的确更新了,所有这些都是Entity 框架在起作用。

      最后学习删除记录,代码如下:

    protected void Page_Load(object sender, EventArgs e)
    {
    Accounting db = new Accounting();
    Invoice invoice = new Invoice
    {
    ID = 1,
    InvoiceDate = DateTime.Now,
    Total = 900
    };
    db.Invoices.Remove(invoice);
    db.SaveChanges();
    db.Invoices.Load();
    GridView1.DataSource = db.Invoices.Local.ToBindingList();
    GridView1.DataBind();
    }

      这里只需要调用Remove方法,即可在数据库中删除该记录。


      步骤4

      在这个步骤中,我们学习如何改变数据模型。假设我们要在Invoice类中增加一个Tax的属性,也需要Entity框架同步在数据库中增加这个字段,下面演示其步骤:

      1)我们在Invoice类中增加Tax这个属性。

      2)如果这时运行工程,则会看到如下的错误提示:

      The model backing the 'Accounting' context has changed since the database was
      created. Either manually delete/update the database, or call
      Database.SetInitializer with an IDatabaseInitializer instance. For example, the
      DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate
      the database, and optionally seed it with new data.

      提示告诉我们,或者这个时候重新手工删除数据库或者使用代码的方法去完成,我们使用代码的方法去完成,只需要在Application_Start事件中编码如下,即可让Entity框架,自动把新增加的属性反映到数据库中:

    void Application_Start(object sender, EventArgs e)
    {
    // Code that runs on application startup
    System.Data.Entity.Database.SetInitializer<Accounting>
    (new System.Data.Entity.DropCreateDatabaseIfModelChanges<Accounting>());
    }

      3) 再次运行工程,会看到数据表中的确增加了Tax这个字段了,如下图:

      步骤5

      注意,在上面的步骤4中,如果类的属性发生变化,则其实是通过代码的方法,重新将旧的数据库DROP掉,然后再新建,这样的话费时费力,而可以通过另外的一个方法实现,即还好我们可以在初始化的过程中添加测试数据,这样每次重新创建数据库的时候,测试数据就会自动加进去了,算是解决了一些问题,方法如下:

      1)在工程项目中,新增加一个类,命名为AccountingInitializer.cs


      2)修改其代码如下:

    public class AccountingInitializer : 
    System.Data.Entity.DropCreateDatabaseIfModelChanges<Accounting>
    {
    protected override void Seed(Accounting context)
    {
    Invoice invoice = new Invoice { Total = 20, InvoiceDate = 
    new DateTime(2011414), Tax = 1.50 }; 
    invoice.LineItems.Add(new LineItem 
    { ItemCost = 2, ProductName = "Test", Units = 4 }); 
    invoice.LineItems.Add(new LineItem 
    { ItemCost = 4, ProductName = "Test 2", Units = 3 }); 
    context.Invoices.Add(invoice);
    context.SaveChanges();
    base.Seed(context);
    }
    }

      其中,在这个类中继承了DropCreateDatabaseIfModelChanges这个类,并且重写了seed这个方法,在这个方法中可以编写新增测试数据。要记得还需要在Application_OnStart事件中编写如下代码:

    void Application_Start(object sender, EventArgs e)
    {
    //在启动过程中执行该段代码 
    System.Data.Entity.Database.SetInitializer<Accounting>
    (new AccountingInitializer());
    }

      小 结

      可以看到,Entity Framework 4.1的确方便了用户的开发操作,能让用户更专注于业务逻辑实体的开发,更符合OOP的思维方式,更多关于Entity Framework的操作,请参考微软的MSDN。

     
     
  • 相关阅读:
    webpy使用mysql数据库操作(web.database)
    python MySQLdb Windows下安装教程及问题解决方法(python2.7)
    python使用模板手记
    React常用方法手记
    PHP进阶知识
    Javascript文件加载:LABjs和RequireJS
    Debug的F5~F8用法
    myeclipse中导入的jquery文件报错(出现红叉叉,提示语法错误)
    Spring-data-jpa详解
    <c:if test="value ne, eq, lt, gt,...."> 用法
  • 原文地址:https://www.cnblogs.com/jx0906/p/2873406.html
Copyright © 2020-2023  润新知