国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Entity Framework的原理及使用方式

Entity Framework的原理及使用方式  

2011-06-03 14:25:33|  分類: 默認分類 |  標簽: |字號 訂閱

ADO.NET Entity Framework操作數(shù)據庫的過程對用戶是透明的(當然我們可以通過一些工具或方法了解發(fā)送到數(shù)據庫的SQL語句等)。我們唯一能做的是操作EDM,EDM會將這個操作請求發(fā)往數(shù)據庫。

    Entity Framework實現(xiàn)了一套類似于ADO.NET2.0中連接類(它們使用方式相同,均基于Provider模式)的被稱作EntityClient的類用來操作EDM。ADO.NET2.0的連接類是向數(shù)據庫發(fā)送SQL命令操作表或視圖,而EntityClient是向EDM發(fā)送EntitySQL操作Entity。EntityClient在EntityFramework中的作用是相當重要的,所有發(fā)往EDM的操作都是經過EntityClient,包括使用LINQ to Entity進行的操作。

各種使用方式總結

    上文提到對EDM的操作,首先通過一個圖來展現(xiàn)一下目前我們可用的操作的EDM的方式:

 

這幾種訪問方式使用介紹如下:(部分示例代碼來源MSDN Magzine)

  1. EntityClient+EntitySQL

    示例代碼:

string city = "London";

using (EntityConnection cn = new EntityConnection("Name=Entities"))

{

cn.Open();

EntityCommand cmd = cn.CreateCommand();

cmd.CommandText = @"SELECT VALUE c FROM Entities.Customers AS c WHERE

c.Address.City = @city";

cmd.Parameters.AddWithValue("city", city);

DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);

while (rdr.Read())

Console.WriteLine(rdr["CompanyName"].ToString());

rdr.Close();

}

 

  1. ObjectService+EntitySQL

在有EntityClient+EntitySQL這種使用方式下,使用ObjectService+EntitySQL的方式是多此一舉,不會得到任何編輯時或運行時的好處。在ObjectContext下使用EntitySQL的真正作用是將其與LINQ to Entity結合使用。具體可見下文所示。

示例代碼:

string city = "London";

using (Entities entities = new Entities())

{

ObjectQuery<Customers> query = entities.CreateQuery<Customers>(

"SELECT VALUE c FROM Customers AS c WHERE c.Address.City = @city",

new ObjectParameter("city", city)

);

 

foreach (Customers c in query)

Console.WriteLine(c.CompanyName);

}

 

  1. ObjectContext+LINQ( to Entity)

    方式一:

string city = "London";

using (Entities entities = new Entities())

{

var query = from c in entities.Customers

where c.Address.City == city

select c;

 

foreach (Customers c in query)

Console.WriteLine(c.CompanyName);

}

    方式二:

string city = "London";

using (Entities entities = new Entities())

{

var query = entities.Customers.Where(r => r.Address.City == city);

 

foreach (Customers c in query)

Console.WriteLine(c.CompanyName);

}

這兩段示例代碼中的entities.Customer的寫法隱式調用了2中示例的ObjectQuery<Customers>來進行查詢(關于此可以參見EDM的設計器文件-xxx.designer.cs)。在方式二中的Where方法傳入的是一個Lambda表達式,你也可以傳入一條EntitySQL語句做參數(shù)來將LINQ與EntitySQL結合使用。如下代碼演示其使用:

string city = "London";

using (Entities entities = new Entities())

{

var query = entities.Customers.Where("r.Address.City = '"+city+"'");

 

foreach (Customers c in query)

Console.WriteLine(c.CompanyName);

}

使用技巧及需要注意的問題

這也是上文提到的在ObjectContext下使用EntitySQL的一個主要作用,上面的例子比較簡單可能看不到這樣使用的優(yōu)勢,但是如下兩種情況下使用EntitySQL可能是最好的選擇。

  1. 動態(tài)構建查詢條件
    當查詢條件的個數(shù)固定時,我們也可以采用羅列多個Where擴展方法的形式,如下:

    ObjectQuery.Where(LambdaExpression1) .Where(LambdaExpression2)…

    但是當這個條件的存在與否需要在運行時判斷時,我們只能通過組合字符串來得到這個條件,我們可以將條件組合為EntitySQL并傳遞給Where()方法。

  2. 數(shù)據庫模糊查詢

    下面代碼演示使用EntitySQL的like完成模糊查詢:

context.Customer.Where("it.CustomerID LIKE @CustomerID", new System.Data.Objects.ObjectParameter("CustomerID","%V%"));

這個并不是只能使用EntitySQL來實現(xiàn),LINQ to Entity也可以很容易完成。如下代碼:

context.Customer.Where(r => r.CustomerID.Contains("V"));

同理,"V%"、"%V"可以分別使用StartsWith()與EndsWith()函數(shù)實現(xiàn)。

 

    使用LINQ to Entity需要注意的一個方面是,在完成查詢得到需要的結果后使用ToList或ToArray方法將結果轉變?yōu)閮却嬷械膶ο?,然后使用LINQ to Objects來處理,否則處在Entity Framework的聯(lián)機模式下對性能有很大的影響。

 

幾種方法的性能分析及使用選擇

首先用下圖來說明一個執(zhí)行過程。

    圖中所示表達的意思已經非常清楚,稍加解釋的是,無論是通過EntityClient直接提供給Entity Client Data Provider的Entity SQL還是通過ObjectService傳遞的Entity SQL(或是LINQ to Entity),都在Entity Client Data Provider中被解釋為相應的Command Tree,并進一步解釋為對應數(shù)據庫的SQL。這樣來看使用LINQ to Entity與Entity SQL的效率應該差不多,但是還有一個問題,那就是EntitySQL所轉換的最終SQL可能要比LINQ to Entity生成的SQL效率高,這在一定程度上使兩者效率差增大,但是LINQ to Entity有其它技術無法比擬的好處,那就是它的強類型特性,編輯時智能感知提醒,編譯時發(fā)現(xiàn)錯誤,這都是在一個大型項目中所需要的。雖然現(xiàn)在也有了調試EntitySQL的工具,但其與強類型的LINQ to Entity還是有很大差距。

    另外在ObjectService與直接使用EntityClient問題的選擇上。如果你想更靈活的控制查詢過程,或者進行臨時查詢建議選擇EntityCLient,如果是操作數(shù)據那只能采用ObjectService。

 

上文總結了各種操作EDM的方式,下面引用MSDN的一個對這幾種技術進行比較的表格:

  

EntityClient 和實體 SQL

對象服務和實體 SQL

對象服務和 LINQ

定向到 EntityClient 提供程序

適合臨時查詢

可直接發(fā)出 DML

強類型化

可將實體作為結果返回

通過這個表可以很好對某一場合下應該選擇的技術進行判斷。EntityClient 和實體 SQL可以進行最大的控制,而使用LINQ to Entity可以獲得最佳的編輯時支持。

 

其它操作EDM的方式

通過EdmGen更靈活的控制EDM

在.NET Framework 3.5的文件夾下有一個名為EdmGen的工具,Visual Studio的實體設計器就是調用這個工具來完成EDM的生成等操作。通過直接使用這個工具的命令行選項我們可以進行更多的控制。

這個命令的參數(shù)及作用如下:

EdmGen 選項

/mode:EntityClassGeneration 從 csdl 文件生成對象

/mode:FromSsdlGeneration 從 ssdl 文件生成 msl、csdl 和對象

/mode:ValidateArtifacts 驗證 ssdl、msl 和 csdl 文件

/mode:ViewGeneration 從 ssdl、msl 和 csdl 文件生成映射視圖

/mode:FullGeneration 從數(shù)據庫生成 ssdl、msl、csdl 和對象

/project:<字符串> 用于所有項目文件的基名稱 (短格式: /p)

/provider:<字符串> 用于 ssdl 生成的 Ado.Net 數(shù)據提供程序的名稱。(短格式: /prov)

/connectionstring:<連接字符串> 您要連接到的數(shù)據庫的連接字符串 (短格式: /c)

/incsdl:<文件> 從中讀取概念模型的文件

/refcsdl:<文件> 包含 /incsdl 文件所依賴的類型的 csdl 文件

/inmsl:<文件> 從中讀取映射的文件

/inssdl:<文件> 從中讀取存儲模型的文件

/outcsdl:<文件> 將生成的概念模型寫入到其中的文件

/outmsl:<文件> 將生成的映射寫入到其中的文件

/outssdl:<文件> 將生成的存儲模型寫入到其中的文件

/outobjectlayer:<文件> 將生成的對象層寫入到其中的文件

/outviews:<文件> 將預生成的視圖對象寫入到其中的文件

/language:CSharp 使用 C# 語言生成代碼

/language:VB 使用 VB 語言生成代碼

/namespace:<字符串> 用于概念模型類型的命名空間名稱

/entitycontainer:<字符串> 用于概念模型中的 EntityContainer 的名稱

/help 顯示用法信息 (短格式: /?)

/nologo 取消顯示版權消息

 

使用示例:

從 Northwind 示例數(shù)據庫生成完整 Entity Model。

EdmGen /mode:FullGeneration /project:Northwind /provider:System.Data.SqlClient /connectionstring:"server=.\sqlexpress;integrated security=true; database=northwind"

從 ssdl 文件開始生成 Entity Model。

EdmGen /mode:FromSSDLGeneration /inssdl:Northwind.ssdl /project:Northwind

驗證 Entity Model。

EdmGen /mode:ValidateArtifacts /inssdl:Northwind.ssdl /inmsl:Northwind.msl /incsdl:Northwind.csdl

 

為什么要使用Entity Framework,限制條件及當前版本框架的問題

  • 優(yōu)勢

通過對比上面圖4與圖2、圖3我們可以很清楚的看到使用Entity Framework一個很大的好處,我們可以把實體類的定義由一個單獨的項目使用C# class完成這樣一種設計方式轉變?yōu)槭褂脁ml文件定義并集成到數(shù)據訪問層。

    在以往要在一個項目中動態(tài)創(chuàng)建實體,我所知的方法是把要添加的實體放入一個程序集,然后通過反射加載程序集?,F(xiàn)在可以通過動態(tài)更改EDM的方法來增加實體并將其映射到數(shù)據庫,后者是以前無法實現(xiàn)的。

    便于更改數(shù)據庫,當更換數(shù)據庫后,只需修改SSDL的定義,(如果數(shù)據庫的表明有變動,也只需多修改MSL),對CSDL沒有任何影響,從而也不需要對程序的BLL等上層部分做任何改動。

  • 條件

要想讓一個數(shù)據庫支持Entity Framework,一個必要條件就是該數(shù)據庫需提供相應的Entity Client Data Provider,這樣才能將Entity SQL轉換為針對此數(shù)據此數(shù)據庫的SQL并交由ADO.NET來執(zhí)行。當然該數(shù)據庫還需要提供ADO.NET Data Provider。

  • 缺陷

Entity Framework技術的效率問題是其幾乎唯一一個稍有不足之處。首先其將EntitySQL轉換為SQL的方式屬于解釋性轉換,性能較差。另外Entity Framework在每次應用啟動時需要讀取EDM,這個過程較慢(但在后續(xù)操作時,就不再存在這個問題)。

 

EDM中的DML

由于當前的EntitySQL不支持DML操作,所以當前版本的Entity Framework的插入、更新及刪除操作需要通過Object Service來完成。在EDM的設計器文件xxx.designer.cs中自動生成了一些簽名為

void AddToEntity(EntityType entity)

的方法。我們只需要新建一個實體對象并調用這個方法添加實體即可。注意這個函數(shù)內部調用

    entities.AddObject("EntitySetName", entity);

最后調用entities.SaveChanges()方法將修改保存回數(shù)據庫,這是所有三種更新操作所需的。更新與刪除操作都需要先使用ObjectService定位操作的實體對象,更新操作直接使用賦值運算符,刪除操作則調用

    entites.DeleteObject(object o);

方法。之后調用entities.SaveChanges()方法保存,這個過程簡單,不再贅述。

 

含有Association的EDM的使用

    當前版本的Entity Framework不支持自動延遲加載,所有當前未使用的關系中的相關實體默認按不加載處理,當我們需要通過關系獲取一個實體對象時,我們可以采用兩種方法:

  1. 顯示加載
    實體框架針對 EntityReference 類的每個實例提供一個 Load 方法。此方法可用于顯式加載與另一實體相關的一個集合。我們只需在訪問關系中實體之前調用其Load即可,當然提前判斷該實體是否已經加載是一種比較好的實踐。如下代碼所示

using (Entities entities = new Entities())

{

var query = (from o in entities.Orders

where o.Customers.CustomerID == "ALFKI"

select o);

foreach (Orders order in query)

{

if (!order.CustomersReference.IsLoaded)

order.CustomersReference.Load();

Console.WriteLine(order.OrderID + " --- " +

order.Customers.CompanyName);

}

}

  1. 預先加載

    先看代碼示例

using (Entities entities = new Entities())

{

var query = (from o in entities.Orders.Include("Customers")

where o.ShipCountry == "USA"

select o);

 

foreach (Orders order in query)

Console.WriteLine(order.OrderID + " --- " +

order.Customers.CompanyName);

}

查詢中針對 Orders 實體調用的 Include 方法接受了一個參數(shù),該參數(shù)在本示例中將要求查詢不僅要檢索 Orders,而且還要檢索相關的 Customers。這將生成單個 SQL 語句,它會加載滿足 LINQ 查詢條件的所有 Order 和 Customer。

兩種加載關系實體的方式的選擇根據:如果針對關系數(shù)據你只需做一到兩次查詢,則使用顯示加載更高效,如果要持續(xù)訪問關系實體中數(shù)據,則使用預先加載。

 

關系下的添加,更新與刪除與上述操作基本相同,唯一需要注意的是刪除操作不支持級聯(lián)刪除,需要手工遍歷所有的相關項并將其一一刪除。注意這里刪除操作不能使用foreach來遍歷需要刪除的關系實體。取而代之的有兩種方法:

  1. while法

while (result.Order_Details.Count > 0)

{

// 刪除操作

}

  1. ToList法(以非聯(lián)機方式操作)

    var items = result.Order_Details.ToList();

    foreach (var item in items)

    {

    // 刪除操作

    }

最新補充

Entity Framework在開發(fā)中的應用 – Entity Framework與控件

.NET Framework提供了許多xxxDataSource控件,如SqlDataSource,ObjectDataSource等,這些數(shù)據源控件大大方便了我們的數(shù)據綁定操作。不幸的是目前還沒有針對Entity Framework的數(shù)據源控件發(fā)布,但是將數(shù)據綁定到諸如ListBox,Grrdview或DetailsView控件也是很簡單的。這源于使用ObjectContext操作返回的IQueryable<T>對象或是使用EntityClient查詢返回的ObjectQuery對象都實現(xiàn)了IEnumerable接口。這樣很容易將這些數(shù)據綁定到數(shù)據顯示控件。更新操作可以按上文所述在相應的時間處理函數(shù)中寫更新EDM的程序即可。

Entity Framework的鏈接字符串

    默認情況下(Visual Studio對Entity Framework數(shù)據項目的默認設置),EDM這個XML文件被作為資源在編譯時嵌入到程序集中。這種情況下當更改EDM后需要重新編譯這個程序集才能使更改生效。通過更改項目屬性也可以讓EDM作為三個獨立的XML文件存在于項目中。為了讓應用程序可以找到EDM(無論其以什么方式存儲)需要一個鏈接字符串來指示EDM所在的位置。實體模型設計器生成的鏈接字符串如下所示:

<add name="ASSEntities"

connectionString="

metadata=res://*/ass.csdl|

res://*/ass.ssdl|

res://*/ass.msl;

provider=System.Data.SqlClient;

provider connection string="Data Source=(local);Initial Catalog=ASS;Integrated Security=True;MultipleActiveResultSets=True""

providerName="System.Data.EntityClient" />

http://msdn.microsoft.com/zh-cn/library/cc716756.aspx

關鍵的一點應用程序是怎樣找到這個字符串的,對于使用EntityClient的情況,可

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Entity Framework 全面教程詳解(轉)
ADO.NET Entity Framework 學習 1 - VS2010學習 - IC窗口
靈動思緒EF(Entity FrameWork)
Entity Framework 實體框架的形成之旅
Entity Framework體系結構
關于Entity Framework 學習中的POCO
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服