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

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)論
主站蜘蛛池模板: 在线播放人成午夜免费视频 | 变态 调教 视频 国产九色 | 国内精品不卡一区二区三区 | 国产一区二区三区四区在线观看 | 蜜桃日本一道无卡不码高清 | 亚洲日本中文字幕在线 | 国产成人啪一区二区 | 在线观看免费情网站大全 | 爱爱视频免费网址 | 色婷婷狠狠五月综合天色拍 | 亚洲精品99久久久久中文字幕 | 免费高清毛片 | 高清国产一级毛片国语 | 欧美大片a一级毛片视频 | 亚洲成a人 | 综合欧美视频一区二区三区 | 欧美国产日韩精品 | 欧美日本一道高清免费3区 欧美日本一道免费一区三区 | 一本大道香蕉中文在线高清 | 国产区高清 | 亚洲视频免费看 | 亚洲欧美中日韩中文字幕 | 97色在线观看免费视频 | 中文字幕久热精品视频免费 | 东京干手机福利视频 | 一区二区三区国产精品 | 成人高清视频在线观看大全 | 亚洲午夜一区 | 九操网 | 久草免费新视频 | 国产精品永久免费自在线观看 | 中文字幕日本不卡 | 九九精品视频在线播放8 | jzz欧美 | 99视频在线看 | 色综合视频一区二区观看 | 国产一级特黄全黄毛片 | 手机在线国产精品 | 免费福利在线 | 色综合合久久天天综合绕视看 | 国产99在线播放免费 |