1. 程式人生 > >實體框架Entity Framework 4.1快速入門

實體框架Entity Framework 4.1快速入門

  介 紹

  在舊的Entity 框架中,開發者可以從已存在的資料庫中產生業務實體的模型,這種開發方法被稱為資料庫驅動的開發方法。而在4.1的Entity Framework中,支開發者先建立實體業務類,然後再產生相關的資料庫檔案,這種開發方法可以稱為“程式碼先行”的開發方法。這種方法對於開發者來說是很有好處的,首先,會讓開發者從面向物件的思維角度出發,去構建業務邏輯中的實體模型,然後再根據實際的需要去生成資料庫檔案,是真正的面向物件的思維開發方法。

  本文中要使用Entity Framework 4.1,這裡提供下載該框架安裝程式:。

  同時,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 startupSystem.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。