作者:朱明中
ADO.NET Entity Framework 是 .NET Framework 3.5 的功能,所以 Visual Studio 2005 無法開發(fā),需要下載 Visual Studio 2008 來支援 .NET 3.5 的編譯與 LINQ 功能(筆者下筆時(shí)最新版為 Beta 2),不必下載到 Team Suite,可以只下載 Professional(筆者是下載 Professional 與 Team Suite 版本)。
Visual Studio 2008 Professional Edition Beta 2:http://www.microsoft.com/downloads/details.aspx?FamilyID=b98a61ba-99b0-40b7-ab6e-5386a2b94217&DisplayLang=en
Visual Studio 2008 Team Suite Beta 2:http://www.microsoft.com/downloads/details.aspx?displaylang=zh-tw&FamilyID=428c076f-e3ef-4290-9ff4-f6fd8f180b7d
若讀者使用SQL Server 2005,則會需要下載Northwind Sample Database:http://www.microsoft.com/downloads/results.aspx?pocId=&freetext=Northwind&DisplayLang=en
在安裝完 Visual Studio 2008 後,就要下載 ADO.NET Entity Framework:
1. ADO.NET Entity Framework Runtime Library:http://www.microsoft.com/downloads/details.aspx?FamilyID=f1adc5d1-a42e-40a6-a68c-a42ee11186f7&DisplayLang=en
2. ADO.NET Entity Framework Tools August CTP:http://www.microsoft.com/downloads/details.aspx?FamilyID=09a36081-5ed1-4648-b995-6239d0b77cb5&DisplayLang=en
安裝完成後,就可以開始發(fā)展 ADO.NET Entity Framework 應(yīng)用程式了。
若有安裝 Entity Framework Tools August CTP 的話,可以在 Visual Studio 的新增檔案視窗中看到 ADO.NET Entity Data Model 這個(gè)檔案:
這個(gè)檔案就是存放 Conceptual Schema、Storage Schema 與 Mapping Schema 的XML內(nèi)容,讀者可以在新增完成後,用 [Open With…],然後選擇 XML Editor 去打開這個(gè)檔案,就可以看到 Schema 的內(nèi)容。
當(dāng)點(diǎn)選二下 ADO.NET Entity Data Model 後,會出現(xiàn) Entity Data Model Wizard,目前的 Entity Data Model Wizard 允許連接資料庫或自行建立 Entity Model(即手工打造 Schema),若已有資料庫的話,利用 Wizard 直接由資料庫綱要來產(chǎn)生 Entity Schema 比較方便,但若是彈性資料來源(亦即可能有不同的 Data Store)的話,可以選擇手工打造。
Entity Model Wizard 會自動把資料表、檢視表與預(yù)存程序都抓出來,並建立對應(yīng)的 Schema,如此一來,開發(fā)人員只要建立好架構(gòu),就可以直接由程式中使用。
在 Wizard 建立好 Data Model 後,即可完成 Schema 的建立,讀者可以點(diǎn)二下 edmx 檔案,Visual Studio 會載入一個(gè)圖形介面的工具:Entity Model Designer,利用這個(gè)工具,開發(fā)人員可以很輕鬆的建構(gòu)自己的 Entity Model,而不必一個(gè)字一個(gè)字的編寫 Schema 的 XML。若是使用資料庫產(chǎn)生的 Model,則可以看到各個(gè) Entity Model 與其間的關(guān)聯(lián)性。
Entity Model Designer 是一個(gè)可編輯的使用者介面,開發(fā)人員可以直接在上面新增/修改或刪除 Entity 與 Association,所有的修改都會直接反應(yīng)在 Entity Data Model 中。
當(dāng) Entity Model 建立完成後,就可以開始撰寫程式碼來存取 Entity 了。前一篇文章中有提到,開發(fā)人員可以用 LINQ to Entities、EntityClient 或 Object Service 三種方法來存取,所以筆者就以這三種方法來示範(fàn)。
首先是 EntityClient 方法,因?yàn)樗?和ADO.NET 物件模型很相像,所以有用過 ADO.NET 的讀者就很熟悉了,一樣有 Connection,一樣有 Command,也一樣有 DataReader,只是某些地方要注意一下:
string entityClientConnectionString = @"Provider=System.Data.SqlClient; Metadata=.; Provider Connection String='Initial Catalog=Northwind; Integrated Security=SSPI'";
要透過 EntityClient 存取 Entity,就需要使用 Entity SQL,這是一個(gè)特別版本的 Transact-SQL,專供讀取 Entity 之用的,它可以做到許多在資料庫上可用到的功能,不過因?yàn)樗灿幸恍┫拗?,所以需要?xí)慣。最明顯的一個(gè)限制,就是每個(gè)資料表都要設(shè)定別名,然後用別名來存取,例如下列的 SQL:
SELECT CustomerID, ContactName FROM Northwind.Customers
就不能使用,必須要用:
SELECT c.CustomerID, c.ContactName FROM NorthwindEntities.Customers AS c
才可以。
有了以上的知識後,就可以寫出簡單的 EntityClient 存取資料的程式碼:
static void Main(string[] args){string entityClientConnectionString =@"Provider=System.Data.SqlClient; Metadata=.;Provider Connection String='Initial Catalog=Northwind;Integrated Security=SSPI'";using (EntityConnection conn = newEntityConnection(entityClientConnectionString)){conn.Open();EntityCommand cmd = new EntityCommand("SELECT c.CustomerID, c.ContactName FROM NorthwindEntities.Customers AS c",conn);EntityDataReader reader =cmd.ExecuteReader(CommandBehavior.SequentialAccess);while (reader.Read())Console.WriteLine("CustomerID: " + reader.GetValue(0).ToString() +" Customer Name:" + reader.GetValue(1).ToString());reader.Close();conn.Close();}}
是不是覺得和 ADO.NET 存取資料庫很像呢?若是對 ADO.NET 很熟悉,但卻對 Entity Framework 不熟的開發(fā)人員,建議可以由此入門。
Object Service 是一種比 EntityClient 更高階的方法,它一樣可以利用 Entity SQL 來查詢,但利用 for…each… 來替代 EntityDataReader 的功能,也就是它回傳的是每個(gè) Entity 的物件實(shí)體(由 IEnumerate <T> 來回傳),而不是 DataReader,所以可以利用物件瀏覽的方式來存取。
在Object Service 中,每一個(gè) Entities(即 Entity 的集合,在 CSDL 中是 EntityContainer)都是一個(gè)獨(dú)立的個(gè)體,就像 Connection 一樣,而 ObjectQuery <T> 則是 Command,也是由它來驅(qū)動查詢的處理工作,
using (NorthwindEntities context = new NorthwindEntities()){string esql = "SELECT VALUE Customers FROM NorthwindEntities.Customers AS Customers";ObjectQueryquery = new ObjectQuery (esql, context, MergeOption.NoTracking); foreach (Customers customer in query)Console.WriteLine("CustomerID: " + customer.CustomerID + " Contact Name:" + customer.ContactName);}
用 Object Service 比起用 Entity Client 來說單純多了,因?yàn)橹灰褂靡粋€(gè) ObjectQuery <T>,即可存取 Entity 的資料,不過有一個(gè)地方要注意的是,這裡的 Entity SQL 取出的必須是一個(gè) Entity,也就是說你不能用這樣:
SELECT c.CustomerID, c.ContactName FROM NorthwindEntities.Customers AS c
而是要用:
SELECT VALUE c FROM NorthwindEntities.Customers AS c
VALUE 這個(gè)指令是指示,只有一個(gè)項(xiàng)目會被處理到,而且每一列就只有一個(gè)指定的項(xiàng)目而已。
若想要在 Object Service 中存取 Entity 中的 Property,那就必須要用 IExtendedDataRecord 才可以存取,例如把前面那個(gè)例子修改一下:
using (NorthwindEntities context = new NorthwindEntities()){string esql = "SELECT c.CustomerID, c.ContactName FROM NorthwindEntities.Customers AS c";ObjectQuery< IExtendedDataRecord> query = new ObjectQuery< IExtendedDataRecord >(esql, context, MergeOption.NoTracking);foreach (IExtendedDataRecord reader in query)Console.WriteLine("CustomerID: " + reader.GetValue(0).ToString() + " Contact Name:" + reader.GetValue(1).ToString());}
再來,我們就可以利用 C# 3.0(VB 9.0)中的 LINQ 來存取 Entity,首先需要先了解 LINQ 是什麼,它其實(shí)是將程式中的集合資料,使用一個(gè)類似於 SQL 的語法來查詢的,以往我們都要做迴圈,或者呼叫集合提供的 Contains() 方法來判斷,在 LINQ 中,我們可以以簡單的類查詢語法來搜尋集合中的資料,並且把符合條件的輸出來。
LINQ to Entities 是 ADO.NET Entity Framework 開放給 LINQ 查詢的方法,只要學(xué)會了 LINQ 的語法,然後了解 LINQ to Entities 所開放的介面,如此就可以很簡單的查詢 Entity 中的資料,例如:
using (NorthwindEntities db = new NorthwindEntities()){IQueryable<Products> query = db.Products.Where(p => p.UnitPrice > 10 && p.UnitPrice < 30);foreach (var product in query){Console.WriteLine("ProductID: " + product.ProductID +" Name: " + product.ProductName +" Price: " + product.UnitPrice);}}
很簡單吧,而且沒有任何的 SQL 指令,連 Entity SQL 都不用了。
每個(gè) EntityContainer 都是一個(gè) Database,而查詢是透過 EntityContainer 下指令,而這個(gè)指令是由 LINQ to Entities 所開放的,每個(gè)查詢的結(jié)果由 IQueryable <T> 處理,開發(fā)人員只要利用 foreach 來瀏覽 IQueryable <T>,即可以取得查詢結(jié)果。
以下是一個(gè)查詢檢視表的例子:
using (NorthwindEntities db = new NorthwindEntities()){ObjectQuery<Invoices> query = db.Invoices;IQueryable<Invoices> result = from q in queryselect q;foreach (var invoice in result){Console.WriteLine("CustomerID: " + invoice.CustomerID +" ProductID: " + invoice.ProductID +" Name: " + invoice.ProductName +" Price: " + invoice.UnitPrice);}}
本文就最初淺的方式,介紹 ADO.NET Entity Framework 的基本作法與簡單的查詢功能,當(dāng)然還不只這些,未來我們還會繼續(xù)介紹,例如讀寫資料以及 Transaction 的能力,當(dāng)然也有更彈性的 Meta Service 以及介面查詢方法。
聯(lián)系客服