解釋 EntityClient 和物件服務之間的差異,並介紹將 LINQ 和 EntitySQL 與這些服務一起使用的意義。可使用 LINQ 擷取實體時為什麼要使用實體 SQL?
介紹可用於與 EDM 進行互動的三種主要技術:
· 使用 EntityClient 提供者編寫 EntitySQL 查詢
· 使用物件服務編寫 EntitySQL 查詢
· 使用物件服務編寫 LINQ 查詢
以上每種技術都擁有共同的特徵;例如,都直接或間接使用 EntityClient 提供者。但是,它們產生的結果以及獲得這些結果的方式卻有所不同。
EntityClient 提供者具有一系列對象,如果瞭解 ADO.NET 物件模型,則您應該熟悉這些對象。EntityConnection 用於串連到 EDM,EntityCommand 用於針對 EDM 發出查詢,而命令的結果則通過 DbDataReader 返回。無論是通過物件服務直接還是間接使用 EntityClient,EntityClient 最終都會發出查詢並返回結果。
這使得問題再次擺上案頭,為什麼有 LINQ 卻要使用 EntitySQL?答案在於每種技術的優缺點。
EntityClient + EntitySQL
深入分析:Entity Framework資料載入
許多個物件關係映射架構都支援以下兩種眾所周知的行為,它們有助於編寫短期“探測”代碼、改進應用程式使用資料庫的次數和資料轉送量:
· 積極式載入:每次程式需要操作一組相關對象時,都會在一個先期請求中從資料庫凍結整個圖。
· 消極式載入:當程式瀏覽連線對象圖的屬性時自動從資料庫載入資料,此時可能多次訪問存放庫,但僅載入必需的項目。
為遵循“無隱藏網路往返操作”原則,Entity Framework放棄了自動化消極式載入。遍曆由代碼產生的類所組成的圖這一操作永遠不會針對存放庫觸發查詢。Entity Framework代之以要求使用者代碼在使用之前明確凍結所有對象。
可隨時載入,但在每次要執行載入時需針對引用或集合調用稱為 Load 的方法。實際上,通過幹涉代碼產生過程或通過編寫自己的類,仍可實現隱式消極式載入。但是,更常見的方法是消極式載入而非僅隱藏往返操作。您必須瞭解,每次程式使用消極式載入時,都容易得到一個包含不一致資料的圖。並且,如果程式不及時重新整理已載入的資料,圖中的資料就可能會失效。
通過使用 EntityClient API 編寫代碼,可最精細地控制這三種技術。可建立 EntityConnection 來串連 EDM,以 EntitySQL 編寫一個查詢並使用 EntityCommand 執行該查詢,然後通過 DbDataReader 返回結果。此技術要精簡一些,省去了 LINQ 和物件服務提供的一些文法修飾。
EntitySQL 最大的優點是其靈活性。基於字串的文法有助於輕鬆地構建動態查詢。如果需要建立臨時查詢,它將非常有用。但是,這種靈活和精簡也使得只能通過 DbDataReader 返回結果。無法使用 EntityClient 和 EntitySQL 從 EDM 返回純實體。DbDataReader 可供檢索並用於在滿足 EntitySQL 查詢的行集合中執行迭代。
物件服務 + EntitySQL
另一技術是使用物件服務並利用 EntitySQL 來執行查詢。從而不再與 EntityClient 提供者直接互動(儘管實際上它仍會與提供者通訊)。使用 ObjectContext 和 ObjectQuery<T> 來針對 EDM 發出查詢。
此技術非常適合於發出臨時查詢(與第一種技術相同)。但是,它不是通過 DbDataReader 返回資料,將物件服務與 EntitySQL 一起使用時可從 EDM 返回實體。因此,可牢靠地提供以下優點:查詢靈活且返回最佳實體。可使用此技術從 EDM 檢索實體,然後使用 ObjectContext 中的 SaveChanges 方法來更新實體。
物件服務 + LINQ
將物件服務 LINQ 一起使用並不適合於臨時查詢,這一點與其他技術不同。
因此,為什麼有 LINQ 卻要使用實體 SQL?如果需要臨時查詢或希望建立比使用 LINQ 實現的查詢更加靈活的查詢,則應使用實體 SQL。否則,建議使用 LINQ 和物件服務,以便可受益於其強型別化以及返回實體和投影的功能。
如使用 LINQ 的強型別化文法,還可在設計時發現許多錯誤,不必等到運行應用程式時才發現。我非常喜歡這一功能——它使我可以一心一意編寫代碼,不必通過執行構建和運行來找出錯誤。
ObjectContext 的作用是什嗎? ObjectContext 是到物件服務的 EntityConnection 的通道。它通過底層 EntityConnection 提供對 EDM 的訪問。例如,可通過 ObjectContext 訪問實體,詢問 ObjectContext 以找出有關對象狀態的資訊,以及使用 CreateQuery 方法建立 ObjectQuery<T> 查詢。
ObjectContext 的另一目的是為對象提供擷取資料庫條目更新資訊的方法。例如,可使用 ObjectContext 方法來將實體添加到 ObjectContext、刪除實體、操作實體以及最終將實體更改儲存到資料庫(通過 SaveChanges 方法)。
結束語