中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

LINQ查詢的效果舉例分析

發布時間:2021-12-02 09:31:03 來源:億速云 閱讀:156 作者:iii 欄目:編程語言

本篇內容介紹了“LINQ查詢的效果舉例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

LINQ查詢的一點體會

當我們會熟練的使用以上的查詢方法對數據庫里的內容做各種各樣的查詢以后,就應當要了解這些數據庫操作的機制,及時調整各種數據操作語句,以較高的效率運行。那么,下面我們來看看LINQ的數據庫操作,看看她都做了些什么工作。

與NHibernate來比較,LINQ在O/R Mapping的性能與可控性上確實優于NHibernate,首先,Linq默認的數據映射采用的是Attribute來實現,這是.NET特有的語法,在編譯時就已經決定了數據對象的各種屬性,而NHibernate等大多數O/RMapping工具仍然采用XML映射文件來描述數據對象的屬性,從外部文件上讀取數據對象的屬性,顯然運行時效率要有所損失。其次,在獲得數據的方式上也有所差別,LINQ中強大的SQL分析機制,可以分析出各種數據操作的SQL語句,并且進行優化,其效率的提升也是顯而易見的。

當然,作為一個O/R Mapping的工具來說,其效率一定達不到直接使用SQL語句訪問數據庫的效率,也就是我們通常所說的SqlDataReader/SqlDataAdapter訪問數據庫,但是,Linq的表現卻給了我們非常大的驚喜,我做了一個測試,使用SqlDataReader和LINQ做相同的大批量數據查詢時,落后竟然不到10%,而NHibernate的查詢效率,卻低了很多,幾乎慢了1倍。對于如此強大的數據映射功能,這樣的效率是我們可以接受的。但是很可惜的一點是,LINQ目前只能支持對SQLServer的支持(但可以支持XML、Entity等)。

在使用LINQ查詢進行數據查詢上,我們通過對LINQ生成的SQL語句進行分析,便可以優化查詢,這是非常方便的,但是,針對數據更新的效率問題,我們不得不談談LINQ的數據更新機制,一般情況下,數據更新我們會這么做:

var query = from emp in dbdata.Employees   where emp.DepId=="1001" select emp;     Employee employee = query.First();     employee.EmployeeName = "李四";     dbdata.SubmitChanges();

對于以上這段代碼,我們可以看出,其功能是從Employee表中取出部門代碼為1001的所有員工,然后我們取出***條數據(這里為了簡便,我們僅僅取出***條,其實可以用Where取出滿足條件的記錄),然后把名字修改成“李四”,再更新到數據庫中。這段代碼,LINQ都干了些什么呢?通過查詢從數據庫中取出若干條記錄,放在內存中,并且都標記為new(未改變)狀態,當修改了員工姓名的時候,被修改的對象被標記為Dirty(已改變),在SubmitChanges的時候,再為內存中對象狀態為Dirty的記錄自動生成SQL語句并執行,也就是說,我們要完成一次數據的更新,至少要完成一次查詢和一次更新。

LINQ查詢的一點分析:

由于采用了延時加載(Layze Load)的技術,在以上語句中實際從數據庫中取出的記錄只有1條,更新的時候也只更新這一條,因此效率仍然是非常高的,我在測試的過程中發現,從250000條數據中隨機抽取一條進行更新,實際的效率和從10條數據中隨機抽取一條進行更新幾乎沒有差別,因為比較更新狀態是在內存中進行,因此效率是比較高的。下面我們再看看實際的更新生成了什么樣的SQL語句:

UPDATE [dbo].[Employee] SET [EmployeeName] =   @p4 WHERE ([EmployeeId] = @p0) AND ([DepId] = @p1) AND    ([EmployeeName] = @p2) AND ([EmployeeSalary] = @p3)

原來,我們只修改了EmployeeName的字段,生成的SQL語句卻也僅僅是更新了Employee字段。那么,我們再看看后面的條件,為什么會包含除了主鍵以外的其他條件呢?原來,這也是LINQ自動生成SQL語句的嚴謹所在,這是為了防止并發情況下,多個事務針對同一條記錄更新時發生錯誤,假如A事務更新了該記錄,則B事務更新會失敗。我們不禁要問,假如要更新主鍵字段怎么辦?會不會錯誤的更新到多條記錄呢?答案是肯定的,肯定會錯誤的更新到其他記錄,因此,LINQ中規定了主鍵字段是不允許更新的,如果確實要更新,那么就刪除掉該記錄,重新插入新紀錄。這么嚴謹的SQL語句,會給我們帶來一些麻煩,我們來看下面一個應用場景:

如果我們在表中設有一個字段用于計數器,使用SQL語句是這樣的:

Update CountTable set CountColumn=  CountColumn+1 where CountId=@countId

但使用LINQ生成的Sql語句卻是:

UPDATE [dbo].[CountTable] SET [CountColumn] = @p2   WHERE ([CountId] = @p0) AND ([CountColumn] = @p1)

@p2這個參數是計算好后傳入的,@p1這個參數是CountColumn原來的值。也就是說,CountColumn+1這個值不是由數據庫運算出來的,這樣一來,當并發數很高的時候,我們往往會更新失敗。我做了個測試,使用多線程模擬多用戶的情況下進行計數統計,數據庫中統計的值比使用靜態變量保存的值要小,這也就是說數據庫更新是存在失敗的情況。另外,這樣每次的更新,需要完成的操作有查找和更新兩個步驟,因此對于效率也有比較大的影響。

在這里,我們并不是要說明LINQ存在缺陷,因為這種情況可能在任何的O/R Mapping的框架下都得不到很好的解決,這里僅僅是想告訴我們,只有了解系統內部運行的情況,才能設計出效率更高,更可靠的系統。

“LINQ查詢的效果舉例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淳安县| 哈巴河县| 昭平县| 栾城县| 楚雄市| 永川市| 克东县| 陆川县| 响水县| 衡阳市| 岚皋县| 柳林县| 平顶山市| 乃东县| 敖汉旗| 东平县| 昌吉市| 嵊泗县| 中阳县| 涿鹿县| 昔阳县| 时尚| 南和县| 沧源| 楚雄市| 芦溪县| 洪洞县| 达孜县| 来安县| 阳高县| 罗田县| 甘孜| 汉源县| 乐平市| 海城市| 深泽县| 丹江口市| 阿坝| 大城县| 乐业县| 贵德县|