欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

EF 優化

系統 1730 0

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


l ? ? ? ? MergeOption.NoTracking


當我們只需要讀取某些數據而不需要刪除、更新的時候,可以指定使用MergeOption.NoTracking的方式來執行只讀查詢(EF默認的方式是AppendOnly)。當指定使用NoTracking來進行只讀查詢時,與實體相關的引用實體不會被返回,它們會被自動設置為null。因此,使用NoTracking可以提升查詢的性能。示例代碼如下:


[ Test ]

?

? ? ? ? public void NoTrackingTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

// 針對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方法獲取數據時,它首先會查詢是否有緩存,如果有緩存則從緩存中返回需要的實體。如果沒有則查詢數據庫,返回需要的實體,并添加在緩存中以便下次使用。
First: 總從數據庫中提取需要的實體。
因此,我們應在合適的地方選擇GetObjectByKey方法來獲取數據,以減少對數據庫的訪問提升性能。示例代碼如下:


[ Test ]

?

? ? ? ? public void GetByKeyTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? // 從數據庫中提取數據

?

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

?

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

?

?

?

? ? ? ? ? ? ? ? // 將從緩存中提取數據

?

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

?

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

?

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

?

?

?

?

?

? ? ? ? ? }


? ? ? ?}
此外,需要注意的是如果 GetObjectByKey 沒有獲取到符合條件的數據,那么它會拋異常。為了避免此情況發生,在有可能出現異常的地方,我們應該使用 TryGetObjectByKey 方法。 TryGetObjectByKey 方法獲取數據的方式和 GetObjectByKey 類似,只是當沒有取到符合條件的數據時, TryGetObjectByKey 會返回 null 而不是拋異常。示例代碼如下:


[ Test ]

?

? ? ? ? public void TryGetByKeyTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

?

?

? ? ? ? ? ? ? ? // 沒有符合條件的數據會有異常拋出

?

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

?

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

?

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

?

?

?

? ? ? ? ? ? ? ? // 沒有符合條件的數據會有返回null

?

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

?

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

?

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

?

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

?

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

?

?

?

? ? ? ? ? ?}


? ? ? ?}


l ? ? ? ? First /FirstOrDefault


First: 當我們使用First來獲取數據,如果沒有符合條件的數據,那么我們的代碼將會拋出異常。
FirstOrDefault: 當我們使用 FirstOrDefault 來獲取的數據,如果沒有符合條件的數據,那么它將返回null。
顯然,對于一個良好的代碼,是對可以預見的異常進行處理,而不是等它自己拋出來。示例代碼如下:


[ Test ]

?

? ? ? ? public void FirstTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

?

?

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

?

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

?

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

?

? ? ? ? ? ? ?

?

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

?

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

?

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

?

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

?

? ? ? ? ? ?}


? ? ? ?}


l ? ? ? ? 延遲加載/Include


EF 不支持實體的部分屬性延遲加載,但它支持實體關系的延遲加載。默認情況,實體的關系是不會加載。如下代碼:


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

?

? ? ? ? ? ? ? ?}

?

? ? ? ? ? ?}


? ? ? ?}
上述代碼中,因為Orders沒有被加載,所以在輸出Orders的時候,是不會有任何輸出的。
當我們需要加載某些關聯的關系時,可是用 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關聯的Orders將被加載。

?

l ? ? ? ? CompiledQuery

?

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

?

示例代碼如下:

?

[ Test ]

?

? ? ? ? public void ComplieTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ? // 對查詢進行編譯

?

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

?

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

?

? ? ? ? ? ? ?

?

? ? ? ? ? ? ? ? // 執行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 ? ? ? ? 存儲模型視圖

?

EF 中,當執行實體查詢的時候,運行時首先將實體模型轉換成 ESQL 視圖,而 ESQL 視圖則是根據 msl 文件來生成相應的代碼。此外, ESQL 視圖包含了相應的查詢語句。 ESQL 視圖被創建后將在應用程序域中進行緩存以便下次使用。這個運行時生成存儲模型視圖是比較耗時的過程。

?

為了,免去運行時生成存儲模型視圖,我們可以預先產生這個的存儲模型視圖。具體步驟如下:

?

首先,使用 EdmGen2 來產生存儲模型視圖,相應的命令如下:

?

Edmgen2 /ViewGen cs NorthwindEntites.edmx

?

執行此命令后, edmgen2 會在當前目錄下生成一個名為 NorthwindEntites.GeneratedViews.cs 這個文件,就是我們要使用的存儲模型視圖文件。

?

將此文件添加到項目中就行,其他的代碼不需要改變, EF 會自動調用此視圖文件。如下示例代碼:

?

[ Test ]

?

? ? ? ? public void ViewTest()

?

? ? ? ?{

?

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

?

? ? ? ? ? ?{

?

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

?

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

?

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

?

? ? ? ? ? ?}

?

? ? ? ?}

?

沒有使用存儲模型視圖的情況是:

?

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

?

項目中添加了 NorthwindEntites.GeneratedViews.cs 文件,執行情況是:

?

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

?

可見,使用了存儲模型視圖的確是提高了性能。

?

l ? ? ? ? 沖突處理

?

EF 中,默認情況并不會檢查并發沖突。因為 EF 實現的是樂觀的并發模式,當有并發的沖突發生時,將會拋出 Optimistic Concurrency Exception 異常。我們可以通過使用 RefreshMode 這個枚舉來指定當發生沖突時如何處理。

?

RefreshMode 有兩中枚舉值:

?

ClientsWins: 當提交修改,更新數據庫中的值。

?

StoreWins: 放棄修改,使用數據庫中的值。

?

示例代碼片段如下:

?

var db2 = new NorthwindEntities1 ();

?

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

?

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

?

? ? ? ? ? ?{

?

? ? ? ? ? ? ? ?customer2.ContactName = " ♂風車車.Net" ;

?

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

?

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

?

? ? ? ? ? ?}

?

? ? ? ? ? ? try

?

? ? ? ? ? ?{

?

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

?

? ? ? ? ? ?}

?

? ? ? ? ? ? catch ( OptimisticConcurrencyException ex) // 捕獲到沖突,則進行相應的處理

?

? ? ? ? ? ?{

?

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

?

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

?

? ? ? ? ? ?}

?

上述代碼片段,只是說明怎么處理并發沖突,不是具體的并發。(ps:本來是準備開個線程來模擬并發的,但是始終沒成功,沒明白什么原因,望高人指點呢?。?

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

EF 優化


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91视频观看免费 | 亚洲av毛片一区二区久久 | 成人午夜网站 | 四虎影片国产精品8848 | 中文字幕亚洲一区二区三区 | 欧美色综合天天久久综合精品 | 亚洲 欧美 日韩在线 | 亚洲精品黄 | xy110.app| 天堂资源在线 | 欧美大黄 | 成人综合久久精品色婷婷 | 欧美激情视频网站 | 国产精品久久久久不卡 | 99精品国产免费观看视频 | 一级黄色毛片视频 | 亚欧成人中文字幕一区 | 欧美在线观看19 | 精品三级国产精品经典三 | 成人黄色在线观看视频 | 精品国产一级毛片大全 | 亚洲精品一区二区三区在线看 | 国产精品片aa在线观看 | 91欧美精品激情在线观看 | a视频在线播放 | 免费黄色大片在线观看 | 国产福利视频在线观看 | 日韩超碰 | 久久99国产精品 | 国产中文字幕一区 | 国产精品国产三级国产aⅴ 精品视频在线播放 | 国产丫丫视频私人影院 | 亚洲最大视频网站 | 99久久精品国产一区二区三区 | 美女下面直流白浆视频 | 欧日韩视频| 丝袜捆绑调教视频免费区 | 国产日产在线观看 | 视频在线观看一区 | 日韩日韩日韩日韩 | 成人资源在线观看 |