亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

EF 優(yōu)化

系統(tǒng) 1657 0

本文介紹一些改善EF代碼、優(yōu)化其性能的相關(guān)方法,如NoTracking,GetObjectByKey, Include等 ,還包括編譯查詢、存儲(chǔ)模型視圖以及沖突處理等內(nèi)容。


l ? ? ? ? MergeOption.NoTracking


當(dāng)我們只需要讀取某些數(shù)據(jù)而不需要?jiǎng)h除、更新的時(shí)候,可以指定使用MergeOption.NoTracking的方式來(lái)執(zhí)行只讀查詢(EF默認(rèn)的方式是AppendOnly)。當(dāng)指定使用NoTracking來(lái)進(jìn)行只讀查詢時(shí),與實(shí)體相關(guān)的引用實(shí)體不會(huì)被返回,它們會(huì)被自動(dòng)設(shè)置為null。因此,使用NoTracking可以提升查詢的性能。示例代碼如下:


[ Test ]

?

? ? ? ? public void NoTrackingTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

// 針對(duì)Customers查詢將使用MergeOption.NoTracking

?

? ? ? ? ? ? ? ?db.Customers.MergeOption = MergeOption .NoTracking;

?

? ? ? ? ? ? ? ? var cust = db.Customers.Where(c => c.City == "London" );

?

? ? ? ? ? ? ? ? foreach ( var c in cust)

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine(c.CustomerID);

?

?

?

? ? ? ? ? ? ? ? // 也可以這樣寫

?

? ? ? ? ? ? ? ? //var cust1 = ((ObjectQuery<Customers>)cust).Execute(MergeOption.NoTracking);

?

?

?

? ? ? ? ? ? ? ? //Esql 寫法

?

? ? ? ? ? ? ? ? //string esql = "select value c from customers as c where c.CustomerID='ALFKI'";

?

? ? ? ? ? ? ? ? //db.CreateQuery<Customers>(esql).Execute(MergeOption.NoTracking).FirstOrDefault();

?

?

?

? ? ? ? ? ?}


? ? ? ?}


l ? ? ? ? GetObjectByKey/First


GetObjectByKey
在EF中,使用GetObjectByKey方法獲取數(shù)據(jù)時(shí),它首先會(huì)查詢是否有緩存,如果有緩存則從緩存中返回需要的實(shí)體。如果沒(méi)有則查詢數(shù)據(jù)庫(kù),返回需要的實(shí)體,并添加在緩存中以便下次使用。
First: 總從數(shù)據(jù)庫(kù)中提取需要的實(shí)體。
因此,我們應(yīng)在合適的地方選擇GetObjectByKey方法來(lái)獲取數(shù)據(jù),以減少對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)提升性能。示例代碼如下:


[ Test ]

?

? ? ? ? public void GetByKeyTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? // 從數(shù)據(jù)庫(kù)中提取數(shù)據(jù)

?

? ? ? ? ? ? ? ? var cst = db.Customers.First(c => c.CustomerID == "ALFKI" );

?

? ? ? ? ? ? ? ? Console .WriteLine(cst.CustomerID);

?

?

?

? ? ? ? ? ? ? ? // 將從緩存中提取數(shù)據(jù)

?

? ? ? ? ? ? ? ? EntityKey key = new EntityKey ( "NorthwindEntities1.Customers" , "CustomerID" , "ALFKI" );

?

? ? ? ? ? ? ? ? var cst1 = db.GetObjectByKey(key) as Customers ;

?

? ? ? ? ? ? ? ? Console .WriteLine(cst1.CustomerID);

?

?

?

?

?

? ? ? ? ? }


? ? ? ?}
此外,需要注意的是如果 GetObjectByKey 沒(méi)有獲取到符合條件的數(shù)據(jù),那么它會(huì)拋異常。為了避免此情況發(fā)生,在有可能出現(xiàn)異常的地方,我們應(yīng)該使用 TryGetObjectByKey 方法。 TryGetObjectByKey 方法獲取數(shù)據(jù)的方式和 GetObjectByKey 類似,只是當(dāng)沒(méi)有取到符合條件的數(shù)據(jù)時(shí), TryGetObjectByKey 會(huì)返回 null 而不是拋異常。示例代碼如下:


[ Test ]

?

? ? ? ? public void TryGetByKeyTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

?

?

? ? ? ? ? ? ? ? // 沒(méi)有符合條件的數(shù)據(jù)會(huì)有異常拋出

?

? ? ? ? ? ? ? ? EntityKey key = new EntityKey ( "NorthwindEntities1.Customers" , "CustomerID" , " ♂風(fēng)車車.Net" );

?

? ? ? ? ? ? ? ? var cst = db.GetObjectByKey(key) as Customers ;

?

? ? ? ? ? ? ? ? Console .WriteLine(cst.CustomerID);

?

?

?

? ? ? ? ? ? ? ? // 沒(méi)有符合條件的數(shù)據(jù)會(huì)有返回null

?

? ? ? ? ? ? ? ? EntityKey key1 = new EntityKey ( "NorthwindEntities1.Customers" , "CustomerID" , " ♂風(fēng)車車.Net" );

?

? ? ? ? ? ? ? ? Object cst1 = null ;

?

? ? ? ? ? ? ? ?db.TryGetObjectByKey(key1, out cst1);

?

? ? ? ? ? ? ? ? if (cst1 != null )

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine((( Customers )cst1).CustomerID);

?

?

?

? ? ? ? ? ?}


? ? ? ?}


l ? ? ? ? First /FirstOrDefault


First: 當(dāng)我們使用First來(lái)獲取數(shù)據(jù),如果沒(méi)有符合條件的數(shù)據(jù),那么我們的代碼將會(huì)拋出異常。
FirstOrDefault: 當(dāng)我們使用 FirstOrDefault 來(lái)獲取的數(shù)據(jù),如果沒(méi)有符合條件的數(shù)據(jù),那么它將返回null。
顯然,對(duì)于一個(gè)良好的代碼,是對(duì)可以預(yù)見(jiàn)的異常進(jìn)行處理,而不是等它自己拋出來(lái)。示例代碼如下:


[ Test ]

?

? ? ? ? public void FirstTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

?

?

? ? ? ? ? ? ? ? // 拋異常的代碼

?

? ? ? ? ? ? ? ? var cst = db.Customers.First(c => c.CustomerID == " ♂風(fēng)車車.Net" );

?

? ? ? ? ? ? ? ? Console .WriteLine(cst.CustomerID); // 此處將出拋異常

?

? ? ? ? ? ? ?

?

? ? ? ? ? ? ? ? // 推薦的使用如下代碼:

?

? ? ? ? ? ? ? ? var cst1 = db.Customers.FirstOrDefault(c => c.CustomerID == " ♂風(fēng)車車.Net" );

?

? ? ? ? ? ? ? ? if (cst1 != null )

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine(cst1.CustomerID);

?

? ? ? ? ? ?}


? ? ? ?}


l ? ? ? ? 延遲加載/Include


EF 不支持實(shí)體的部分屬性延遲加載,但它支持實(shí)體關(guān)系的延遲加載。默認(rèn)情況,實(shí)體的關(guān)系是不會(huì)加載。如下代碼:


[ Test ]

?

? ? ? ? public void IncludeTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? var csts = db.Customers;

?

? ? ? ? ? ? ? ? foreach ( var c in csts)

?

? ? ? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine(c.CustomerID);

?

? ? ? ? ? ? ? ? ? ? foreach ( var o in c.Orders)

?

? ? ? ? ? ? ? ? ? ? ? ? Console .WriteLine( " ? " + o.OrderID);

?

? ? ? ? ? ? ? ?}

?

? ? ? ? ? ?}


? ? ? ?}
上述代碼中,因?yàn)镺rders沒(méi)有被加載,所以在輸出Orders的時(shí)候,是不會(huì)有任何輸出的。
當(dāng)我們需要加載某些關(guān)聯(lián)的關(guān)系時(shí),可是用 Include 方法,如下代碼所示:


[ Test ]

?

? ? ? ? public void IncludeTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? var csts = db.Customers.Include( "Orders" );

?

? ? ? ? ? ? ? ? foreach ( var c in csts)

?

? ? ? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine(c.CustomerID);

?

? ? ? ? ? ? ? ? ? ? foreach ( var o in c.Orders)

?

? ? ? ? ? ? ? ? ? ? ? ? Console .WriteLine( " ? " + o.OrderID);

?

? ? ? ? ? ? ? ?}

?

? ? ? ? ? ?}

?

? ? ? ?}

?

上述代碼中,Customers關(guān)聯(lián)的Orders將被加載。

?

l ? ? ? ? CompiledQuery

?

提供對(duì)查詢的編譯和緩存以供重新使用。當(dāng)相同的查詢需要執(zhí)行很多遍的時(shí)候,那么我們可以使用 ComplieQuery 將查詢的語(yǔ)句進(jìn)行編譯以便下次使用,這樣可以免去對(duì)同一語(yǔ)句的多次處理,從而改善性能。

?

示例代碼如下:

?

[ Test ]

?

? ? ? ? public void ComplieTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? // 對(duì)查詢進(jìn)行編譯

?

? ? ? ? ? ? ? ? var customer = CompiledQuery .Compile< NorthwindEntities1 , IQueryable < Customers >>(

?

? ? ? ? ? ? ? ? ? ?(database) => database.Customers.Where(c => c.City == "London" ));

?

? ? ? ? ? ? ?

?

? ? ? ? ? ? ? ? // 執(zhí)行20次相同的查詢

?

? ? ? ? ? ? ? ? for ( int i = 0; i < 20; i++)

?

? ? ? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? ? ? DateTime dt = System. DateTime .Now;

?

? ? ? ? ? ? ? ? ? ? foreach ( var c in customer(db))

?

? ? ? ? ? ? ? ? ? ? ? ? Console .WriteLine(c.CustomerID);

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine( DateTime .Now.Subtract(dt).TotalMilliseconds);

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine( "---------------------------------------------------" );

?

? ? ? ? ? ? ? ?}

?

?

?

? ? ? ? ? ? }

?

? }

?

l ? ? ? ? 存儲(chǔ)模型視圖

?

EF 中,當(dāng)執(zhí)行實(shí)體查詢的時(shí)候,運(yùn)行時(shí)首先將實(shí)體模型轉(zhuǎn)換成 ESQL 視圖,而 ESQL 視圖則是根據(jù) msl 文件來(lái)生成相應(yīng)的代碼。此外, ESQL 視圖包含了相應(yīng)的查詢語(yǔ)句。 ESQL 視圖被創(chuàng)建后將在應(yīng)用程序域中進(jìn)行緩存以便下次使用。這個(gè)運(yùn)行時(shí)生成存儲(chǔ)模型視圖是比較耗時(shí)的過(guò)程。

?

為了,免去運(yùn)行時(shí)生成存儲(chǔ)模型視圖,我們可以預(yù)先產(chǎn)生這個(gè)的存儲(chǔ)模型視圖。具體步驟如下:

?

首先,使用 EdmGen2 來(lái)產(chǎn)生存儲(chǔ)模型視圖,相應(yīng)的命令如下:

?

Edmgen2 /ViewGen cs NorthwindEntites.edmx

?

執(zhí)行此命令后, edmgen2 會(huì)在當(dāng)前目錄下生成一個(gè)名為 NorthwindEntites.GeneratedViews.cs 這個(gè)文件,就是我們要使用的存儲(chǔ)模型視圖文件。

?

將此文件添加到項(xiàng)目中就行,其他的代碼不需要改變, EF 會(huì)自動(dòng)調(diào)用此視圖文件。如下示例代碼:

?

[ Test ]

?

? ? ? ? public void ViewTest()

?

? ? ? ?{

?

? ? ? ? ? ? using ( var db = new NorthwindEntities1 ())

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? var suppliers = db.Suppliers;

?

? ? ? ? ? ? ? ? foreach ( var s in suppliers)

?

? ? ? ? ? ? ? ? ? ? Console .WriteLine(s.ContactName);

?

? ? ? ? ? ?}

?

? ? ? ?}

?

沒(méi)有使用存儲(chǔ)模型視圖的情況是:

?

1 passed, 0 failed, 0 skipped, took 7.09 seconds.

?

項(xiàng)目中添加了 NorthwindEntites.GeneratedViews.cs 文件,執(zhí)行情況是:

?

1 passed, 0 failed, 0 skipped, took 5.38 seconds.

?

可見(jiàn),使用了存儲(chǔ)模型視圖的確是提高了性能。

?

l ? ? ? ? 沖突處理

?

EF 中,默認(rèn)情況并不會(huì)檢查并發(fā)沖突。因?yàn)? EF 實(shí)現(xiàn)的是樂(lè)觀的并發(fā)模式,當(dāng)有并發(fā)的沖突發(fā)生時(shí),將會(huì)拋出 Optimistic Concurrency Exception 異常。我們可以通過(guò)使用 RefreshMode 這個(gè)枚舉來(lái)指定當(dāng)發(fā)生沖突時(shí)如何處理。

?

RefreshMode 有兩中枚舉值:

?

ClientsWins: 當(dāng)提交修改,更新數(shù)據(jù)庫(kù)中的值。

?

StoreWins: 放棄修改,使用數(shù)據(jù)庫(kù)中的值。

?

示例代碼片段如下:

?

var db2 = new NorthwindEntities1 ();

?

? ? ? ? ? ? var customer2 = db2.Customers.FirstOrDefault(c => c.CustomerID == "2009" );

?

? ? ? ? ? ? if (customer2 != null )

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ?customer2.ContactName = " ♂風(fēng)車車.Net" ;

?

? ? ? ? ? ? ? ?customer2.City = "CD" ;

?

? ? ? ? ? ? ? ?customer2.Region = "GX" ;

?

? ? ? ? ? ?}

?

? ? ? ? ? ? try

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ?db2.SaveChanges();

?

? ? ? ? ? ?}

?

? ? ? ? ? ? catch ( OptimisticConcurrencyException ex) // 捕獲到?jīng)_突,則進(jìn)行相應(yīng)的處理

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ?db2.Refresh( RefreshMode .ClientWins, customer2);

?

? ? ? ? ? ? ? ?db2.SaveChanges();

?

? ? ? ? ? ?}

?

上述代碼片段,只是說(shuō)明怎么處理并發(fā)沖突,不是具體的并發(fā)。(ps:本來(lái)是準(zhǔn)備開(kāi)個(gè)線程來(lái)模擬并發(fā)的,但是始終沒(méi)成功,沒(méi)明白什么原因,望高人指點(diǎn)呢!)

出處:
http://www.cnblogs.com/xray2005

EF 優(yōu)化


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久久亚洲精品永久网站 | 深夜影院在线观看 | 久久精品影院一区二区三区 | 一区在线观看 | 欧美777| 一区二区三区四区在线观看视频 | 日韩一级欧美一级毛片在线 | 成年香蕉大黄美女美女 | 888奇米影视 | 手机看片精品高清国产日韩 | 一级片手机在线观看 | 午夜视频网站在线观看 | 日本免费高清一区 | 国产青色 | 香蕉观看在线视频成人 | 亚洲宗合 | 99久热re在线精品视频 | 亚洲欧洲毛片 | 欧美毛片性视频区 | 一级肉体毛片视频免费看看 | 亚洲成a人v大片在线观看 | 久久这里只精品热在线8 | 青草青草久热精品视频99 | 香蕉视频免费看 | 国产 日韩 一区 | 国产免费青青青免费视频观看 | 亚洲国产最新在线一区二区 | 97国产精品| 久久久久久久99精品免费观看 | 深夜福利成人 | 久久96国产精品 | 欧美性视频一区二区三区 | 欧美成人性视频在线黑白配 | 在线观看成人影院 | 欧美毛片aaaaa片久久久久 | 狠狠色伊人亚洲综合成人 | 国产伦精品一区二区三区无广告 | 看免费黄色一级视频 | 天天天天鲁天天拍一拍 | 国产精品欧美亚洲韩国日本 | 欧美成人xx免费视频 |