首次接觸 ADO.NET Entity Framework

建立開發環境

ADO.NET Entity Framework 是 .NET Framework 3.5 的功能,所以 Visual Studio 2005 無法開發,需要下載 Visual Studio 2008 來支援 .NET 3.5 的編譯與 LINQ 功能(筆者下筆時最新版為 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

安裝完成後,就可以開始發展 ADO.NET Entity Framework 應用程式了。

開發介面初體驗

若有安裝 Entity Framework Tools August CTP 的話,可以在 Visual Studio 的新增檔案視窗中看到 ADO.NET Entity Data Model 這個檔案:

這個檔案就是存放 Conceptual Schema、Storage Schema 與 Mapping Schema 的XML內容,讀者可以在新增完成後,用 [Open With…],然後選擇 XML Editor 去打開這個檔案,就可以看到 Schema 的內容。

當點選二下 ADO.NET Entity Data Model 後,會出現 Entity Data Model Wizard,目前的 Entity Data Model Wizard 允許連接資料庫或自行建立 Entity Model(即手工打造 Schema),若已有資料庫的話,利用 Wizard 直接由資料庫綱要來產生 Entity Schema 比較方便,但若是彈性資料來源(亦即可能有不同的 Data Store)的話,可以選擇手工打造。

Entity Model Wizard 會自動把資料表、檢視表與預存程序都抓出來,並建立對應的 Schema,如此一來,開發人員只要建立好架構,就可以直接由程式中使用。

在 Wizard 建立好 Data Model 後,即可完成 Schema 的建立,讀者可以點二下 edmx 檔案,Visual Studio 會載入一個圖形介面的工具:Entity Model Designer,利用這個工具,開發人員可以很輕鬆的建構自己的 Entity Model,而不必一個字一個字的編寫 Schema 的 XML。若是使用資料庫產生的 Model,則可以看到各個 Entity Model 與其間的關聯性。

Entity Model Designer 是一個可編輯的使用者介面,開發人員可以直接在上面新增/修改或刪除 Entity 與 Association,所有的修改都會直接反應在 Entity Data Model 中。

存取 Entity -使用 Entity Client

當 Entity Model 建立完成後,就可以開始撰寫程式碼來存取 Entity 了。前一篇文章中有提到,開發人員可以用 LINQ to Entities、EntityClient 或 Object Service 三種方法來存取,所以筆者就以這三種方法來示範。

首先是 EntityClient 方法,因為它 和ADO.NET 物件模型很相像,所以有用過 ADO.NET 的讀者就很熟悉了,一樣有 Connection,一樣有 Command,也一樣有 DataReader,只是某些地方要注意一下:

  • Connection String 的設定法不一樣,以往的 Connection String 是依使用的 ADO.NET 資料提供者而有所不同,在 EntityClient 中則是要套用 Entity 以及與 Entity 相連的資料庫的連接字串,例如:

    string entityClientConnectionString =
        @"Provider=System.Data.SqlClient; Metadata=.; 
       Provider Connection String='Initial Catalog=Northwind; 
       Integrated Security=SSPI'";
    
    

    其中,Metadata=. 的意思是,所有的 Entity Model Schema 都在與執行檔相同的目錄中,Provider 則是資料提供者,Provider Connection String 則是資料提供者連接資料庫所需要的 Connection String。
  • EntityDataReader 的 CommandBehavior 目前只支援 SequentialAccess 一種,SequentialAccess 可以讓讀取資料流不會被快取。

要透過 EntityClient 存取 Entity,就需要使用 Entity SQL,這是一個特別版本的 Transact-SQL,專供讀取 Entity 之用的,它可以做到許多在資料庫上可用到的功能,不過因為它也有一些限制,所以需要習慣。最明顯的一個限制,就是每個資料表都要設定別名,然後用別名來存取,例如下列的 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 = new 
EntityConnection(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 不熟的開發人員,建議可以由此入門。

存取 Entity -使用 Object Service

Object Service 是一種比 EntityClient 更高階的方法,它一樣可以利用 Entity SQL 來查詢,但利用 for…each… 來替代 EntityDataReader 的功能,也就是它回傳的是每個 Entity 的物件實體(由 IEnumerate <T> 來回傳),而不是 DataReader,所以可以利用物件瀏覽的方式來存取。

在Object Service 中,每一個 Entities(即 Entity 的集合,在 CSDL 中是 EntityContainer)都是一個獨立的個體,就像 Connection 一樣,而 ObjectQuery <T> 則是 Command,也是由它來驅動查詢的處理工作,

using (NorthwindEntities context = new NorthwindEntities())
{
    string esql = 
    "SELECT VALUE Customers FROM NorthwindEntities.Customers AS Customers";
    ObjectQuery query = 
    new ObjectQuery(esql, context, MergeOption.NoTracking);

    foreach (Customers customer in query)
        Console.WriteLine("CustomerID: " + customer.CustomerID + 
               " Contact Name:" + customer.ContactName);
}

用 Object Service 比起用 Entity Client 來說單純多了,因為只要使用一個 ObjectQuery <T>,即可存取 Entity 的資料,不過有一個地方要注意的是,這裡的 Entity SQL 取出的必須是一個 Entity,也就是說你不能用這樣:

SELECT c.CustomerID, c.ContactName FROM NorthwindEntities.Customers AS c

而是要用:

SELECT VALUE c FROM NorthwindEntities.Customers AS c

VALUE 這個指令是指示,只有一個項目會被處理到,而且每一列就只有一個指定的項目而已。

若想要在 Object Service 中存取 Entity 中的 Property,那就必須要用 IExtendedDataRecord 才可以存取,例如把前面那個例子修改一下:

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());
}

存取 Entity -使用 LINQ to Entities

再來,我們就可以利用 C# 3.0(VB 9.0)中的 LINQ 來存取 Entity,首先需要先了解 LINQ 是什麼,它其實是將程式中的集合資料,使用一個類似於 SQL 的語法來查詢的,以往我們都要做迴圈,或者呼叫集合提供的 Contains() 方法來判斷,在 LINQ 中,我們可以以簡單的類查詢語法來搜尋集合中的資料,並且把符合條件的輸出來。

LINQ to Entities 是 ADO.NET Entity Framework 開放給 LINQ 查詢的方法,只要學會了 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 都不用了。

每個 EntityContainer 都是一個 Database,而查詢是透過 EntityContainer 下指令,而這個指令是由 LINQ to Entities 所開放的,每個查詢的結果由 IQueryable <T> 處理,開發人員只要利用 foreach 來瀏覽 IQueryable <T>,即可以取得查詢結果。

以下是一個查詢檢視表的例子:

using (NorthwindEntities db = new NorthwindEntities())
{
    ObjectQuery<Invoices> query = db.Invoices;

    IQueryable<Invoices> result = from q in query
                             select q;

    foreach (var invoice in result)
    {
        Console.WriteLine(
            "CustomerID: " + invoice.CustomerID +
            " ProductID: " + invoice.ProductID +
            " Name: " + invoice.ProductName +
            " Price: " + invoice.UnitPrice);
    }
}

下一步

本文就最初淺的方式,介紹 ADO.NET Entity Framework 的基本作法與簡單的查詢功能,當然還不只這些,未來我們還會繼續介紹,例如讀寫資料以及 Transaction 的能力,當然也有更彈性的 Meta Service 以及介面查詢方法。

原文地址:https://www.cnblogs.com/jes_shaw/p/1508723.html