久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Entity Framework的原理及使用方式

 orion360doc 2011-11-08

Entity Framework的原理及使用方式  

2011-06-03 14:25:33|  分類(lèi): 默認(rèn)分類(lèi) |  標(biāo)簽: |字號(hào) 訂閱

ADO.NET Entity Framework操作數(shù)據(jù)庫(kù)的過(guò)程對(duì)用戶(hù)是透明的(當(dāng)然我們可以通過(guò)一些工具或方法了解發(fā)送到數(shù)據(jù)庫(kù)的SQL語(yǔ)句等)。我們唯一能做的是操作EDM,,EDM會(huì)將這個(gè)操作請(qǐng)求發(fā)往數(shù)據(jù)庫(kù)。

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

各種使用方式總結(jié)

    上文提到對(duì)EDM的操作,,首先通過(guò)一個(gè)圖來(lái)展現(xiàn)一下目前我們可用的操作的EDM的方式:

 

這幾種訪(fǎng)問(wèn)方式使用介紹如下:(部分示例代碼來(lái)源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的方式是多此一舉,不會(huì)得到任何編輯時(shí)或運(yùn)行時(shí)的好處,。在ObjectContext下使用EntitySQL的真正作用是將其與LINQ to Entity結(jié)合使用,。具體可見(jiàn)下文所示。

示例代碼:

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的寫(xiě)法隱式調(diào)用了2中示例的ObjectQuery<Customers>來(lái)進(jìn)行查詢(xún)(關(guān)于此可以參見(jiàn)EDM的設(shè)計(jì)器文件-xxx.designer.cs),。在方式二中的Where方法傳入的是一個(gè)Lambda表達(dá)式,,你也可以傳入一條EntitySQL語(yǔ)句做參數(shù)來(lái)將LINQ與EntitySQL結(jié)合使用。如下代碼演示其使用:

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

}

使用技巧及需要注意的問(wèn)題

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

  1. 動(dòng)態(tài)構(gòu)建查詢(xún)條件
    當(dāng)查詢(xún)條件的個(gè)數(shù)固定時(shí),,我們也可以采用羅列多個(gè)Where擴(kuò)展方法的形式,,如下:

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

    但是當(dāng)這個(gè)條件的存在與否需要在運(yùn)行時(shí)判斷時(shí),我們只能通過(guò)組合字符串來(lái)得到這個(gè)條件,,我們可以將條件組合為EntitySQL并傳遞給Where()方法,。

  2. 數(shù)據(jù)庫(kù)模糊查詢(xún)

    下面代碼演示使用EntitySQL的like完成模糊查詢(xún):

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

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

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

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

 

    使用LINQ to Entity需要注意的一個(gè)方面是,,在完成查詢(xún)得到需要的結(jié)果后使用ToList或ToArray方法將結(jié)果轉(zhuǎn)變?yōu)閮?nèi)存中的對(duì)象,然后使用LINQ to Objects來(lái)處理,,否則處在Entity Framework的聯(lián)機(jī)模式下對(duì)性能有很大的影響,。

 

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

首先用下圖來(lái)說(shuō)明一個(gè)執(zhí)行過(guò)程。

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

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

 

上文總結(jié)了各種操作EDM的方式,,下面引用MSDN的一個(gè)對(duì)這幾種技術(shù)進(jìn)行比較的表格:

  

EntityClient 和實(shí)體 SQL

對(duì)象服務(wù)和實(shí)體 SQL

對(duì)象服務(wù)和 LINQ

定向到 EntityClient 提供程序

適合臨時(shí)查詢(xún)

可直接發(fā)出 DML

強(qiáng)類(lèi)型化

可將實(shí)體作為結(jié)果返回

通過(guò)這個(gè)表可以很好對(duì)某一場(chǎng)合下應(yīng)該選擇的技術(shù)進(jìn)行判斷。EntityClient 和實(shí)體 SQL可以進(jìn)行最大的控制,,而使用LINQ to Entity可以獲得最佳的編輯時(shí)支持,。

 

其它操作EDM的方式

通過(guò)EdmGen更靈活的控制EDM

在.NET Framework 3.5的文件夾下有一個(gè)名為EdmGen的工具,Visual Studio的實(shí)體設(shè)計(jì)器就是調(diào)用這個(gè)工具來(lái)完成EDM的生成等操作,。通過(guò)直接使用這個(gè)工具的命令行選項(xiàng)我們可以進(jìn)行更多的控制,。

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

EdmGen 選項(xiàng)

/mode:EntityClassGeneration 從 csdl 文件生成對(duì)象

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

/mode:ValidateArtifacts 驗(yàn)證 ssdl,、msl 和 csdl 文件

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

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

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

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

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

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

/refcsdl:<文件> 包含 /incsdl 文件所依賴(lài)的類(lèi)型的 csdl 文件

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

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

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

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

/outssdl:<文件> 將生成的存儲(chǔ)模型寫(xiě)入到其中的文件

/outobjectlayer:<文件> 將生成的對(duì)象層寫(xiě)入到其中的文件

/outviews:<文件> 將預(yù)生成的視圖對(duì)象寫(xiě)入到其中的文件

/language:CSharp 使用 C# 語(yǔ)言生成代碼

/language:VB 使用 VB 語(yǔ)言生成代碼

/namespace:<字符串> 用于概念模型類(lèi)型的命名空間名稱(chēng)

/entitycontainer:<字符串> 用于概念模型中的 EntityContainer 的名稱(chēng)

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

/nologo 取消顯示版權(quán)消息

 

使用示例:

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

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

從 ssdl 文件開(kāi)始生成 Entity Model,。

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

驗(yàn)證 Entity Model。

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

 

為什么要使用Entity Framework,,限制條件及當(dāng)前版本框架的問(wèn)題

  • 優(yōu)勢(shì)

通過(guò)對(duì)比上面圖4與圖2,、圖3我們可以很清楚的看到使用Entity Framework一個(gè)很大的好處,我們可以把實(shí)體類(lèi)的定義由一個(gè)單獨(dú)的項(xiàng)目使用C# class完成這樣一種設(shè)計(jì)方式轉(zhuǎn)變?yōu)槭褂脁ml文件定義并集成到數(shù)據(jù)訪(fǎng)問(wèn)層,。

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

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

  • 條件

要想讓一個(gè)數(shù)據(jù)庫(kù)支持Entity Framework,,一個(gè)必要條件就是該數(shù)據(jù)庫(kù)需提供相應(yīng)的Entity Client Data Provider,,這樣才能將Entity SQL轉(zhuǎn)換為針對(duì)此數(shù)據(jù)此數(shù)據(jù)庫(kù)的SQL并交由ADO.NET來(lái)執(zhí)行。當(dāng)然該數(shù)據(jù)庫(kù)還需要提供ADO.NET Data Provider,。

  • 缺陷

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

 

EDM中的DML

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

void AddToEntity(EntityType entity)

的方法,。我們只需要新建一個(gè)實(shí)體對(duì)象并調(diào)用這個(gè)方法添加實(shí)體即可。注意這個(gè)函數(shù)內(nèi)部調(diào)用

    entities.AddObject("EntitySetName", entity);

最后調(diào)用entities.SaveChanges()方法將修改保存回?cái)?shù)據(jù)庫(kù),,這是所有三種更新操作所需的,。更新與刪除操作都需要先使用ObjectService定位操作的實(shí)體對(duì)象,更新操作直接使用賦值運(yùn)算符,,刪除操作則調(diào)用

    entites.DeleteObject(object o);

方法,。之后調(diào)用entities.SaveChanges()方法保存,這個(gè)過(guò)程簡(jiǎn)單,,不再贅述,。

 

含有Association的EDM的使用

    當(dāng)前版本的Entity Framework不支持自動(dòng)延遲加載,所有當(dāng)前未使用的關(guān)系中的相關(guān)實(shí)體默認(rèn)按不加載處理,,當(dāng)我們需要通過(guò)關(guān)系獲取一個(gè)實(shí)體對(duì)象時(shí),,我們可以采用兩種方法:

  1. 顯示加載
    實(shí)體框架針對(duì) EntityReference 類(lèi)的每個(gè)實(shí)例提供一個(gè) Load 方法。此方法可用于顯式加載與另一實(shí)體相關(guān)的一個(gè)集合,。我們只需在訪(fǎng)問(wèn)關(guān)系中實(shí)體之前調(diào)用其Load即可,,當(dāng)然提前判斷該實(shí)體是否已經(jīng)加載是一種比較好的實(shí)踐。如下代碼所示

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. 預(yù)先加載

    先看代碼示例

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

}

查詢(xún)中針對(duì) Orders 實(shí)體調(diào)用的 Include 方法接受了一個(gè)參數(shù),,該參數(shù)在本示例中將要求查詢(xún)不僅要檢索 Orders,,而且還要檢索相關(guān)的 Customers。這將生成單個(gè) SQL 語(yǔ)句,,它會(huì)加載滿(mǎn)足 LINQ 查詢(xún)條件的所有 Order 和 Customer,。

兩種加載關(guān)系實(shí)體的方式的選擇根據(jù):如果針對(duì)關(guān)系數(shù)據(jù)你只需做一到兩次查詢(xún),則使用顯示加載更高效,,如果要持續(xù)訪(fǎng)問(wèn)關(guān)系實(shí)體中數(shù)據(jù),,則使用預(yù)先加載,。

 

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

  1. while法

while (result.Order_Details.Count > 0)

{

// 刪除操作

}

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

    var items = result.Order_Details.ToList();

    foreach (var item in items)

    {

    // 刪除操作

    }

最新補(bǔ)充

Entity Framework在開(kāi)發(fā)中的應(yīng)用 – Entity Framework與控件

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

Entity Framework的鏈接字符串

    默認(rèn)情況下(Visual Studio對(duì)Entity Framework數(shù)據(jù)項(xiàng)目的默認(rèn)設(shè)置),EDM這個(gè)XML文件被作為資源在編譯時(shí)嵌入到程序集中,。這種情況下當(dāng)更改EDM后需要重新編譯這個(gè)程序集才能使更改生效,。通過(guò)更改項(xiàng)目屬性也可以讓EDM作為三個(gè)獨(dú)立的XML文件存在于項(xiàng)目中。為了讓?xiě)?yīng)用程序可以找到EDM(無(wú)論其以什么方式存儲(chǔ))需要一個(gè)鏈接字符串來(lái)指示EDM所在的位置,。實(shí)體模型設(shè)計(jì)器生成的鏈接字符串如下所示:

<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

關(guān)鍵的一點(diǎn)應(yīng)用程序是怎樣找到這個(gè)字符串的,,對(duì)于使用EntityClient的情況,可

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多