成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為你揭曉 Linq更新數(shù)據(jù)是否真的實用?

開發(fā) 后端
網(wǎng)上關(guān)于Linq的教學(xué)鋪天蓋地,我不準備重復(fù),我只寫下我遇到的問題。Linq更新數(shù)據(jù)怎么就那么費勁?

Linq更新數(shù)據(jù)是一種新潮流,但是使用起來很不理想,筆者很是郁悶。

WEB 2.0的網(wǎng)站少不了數(shù)據(jù)庫、數(shù)據(jù)訪問,也是一切操作之本,而VS 2008中***的亮點之一Linq也恰巧是做這個的,所以我的開發(fā)從Linq、從數(shù)據(jù)庫開始。網(wǎng)上關(guān)于Linq的教學(xué)鋪天蓋地,我不準備重復(fù),我只寫下我遇到的問題。Linq更新數(shù)據(jù)怎么就那么費勁?

Linq的全稱是Language Integrated Query ,也就是說Linq是以一個查詢語言的方式出現(xiàn)在我們面前的。在查詢方面Linq做了不少的優(yōu)化,我們不用在費盡心思去拼裝SQL語句、組裝實體等,所有操作在Linq里都是強類型的,我們用C#代碼輕松地寫出漂亮的SQL語句。

那么做為一個查詢語言,Linq更新數(shù)據(jù)方面又是怎么表現(xiàn)的呢?通常來說Linq的更新會以以下的方式出現(xiàn)(絕大部分教程中都是這么寫的)

  1. var ctx = new MyDataContext();  
  2. var user = ctx.Users.Where(u => u.UserId == userId).Single();  
  3. user.UserName = "New User Name";  
  4. ctx.SubmitChanges();  

這些是C#代碼,但是背后做了什么呢?Linq會為我們生成類似一下的SQL語句

***步,查詢

  1. SELECT UserId, UserName, FirstName, LastName,
  2.  CreatTime From User WHERE UserId = @userId 

第二部,更新

  1. UPDATE User SET UserName = @newUserName  
  2. WHERE UserId = @oldUserId, userName = 
  3. @oldUserName, FirstName = @oldFirstName, LastName = @oldLastName  

發(fā)現(xiàn)了什么?首先Linq會取出所有的字段,在user.UserName = "New User Name"的時候,記錄下UserName字段被更新過了,UPDATE時會只更新UserName,但是把之前所有字段的值放在WHERE語句里來做為條件。

Are you kidding?! 這樣的效率實在是太差了吧?!

拋開效率問題,接下來我們看另外一種更新數(shù)據(jù),有個某個字段記錄頁面被訪問的次數(shù),平時我們會用

  1. UPDATE POST SET Views = Views + 1 WHERE PostId = @PostId  

但是如果我們寫下如下C#代碼

  1. var ctx = MyDataContext();  
  2. var post = ctx.Posts.Where(p => p.PostId = @postId).Single();  
  3. post.Views++  
  4. ctx.SubmitChanges();  

Linq更新數(shù)據(jù)會怎么做呢?和上面一樣!取出所有字段,把View加一,用所有字段做為條件(包括Views),更新回去。

設(shè)想一下,這樣一個被頻繁使用的計數(shù)器,兩次操作出現(xiàn)SELECT與UPDATE交叉情況的可能性很大,那么后者還能更新成功么?

微軟就是這樣解釋的,如果在你Linq更新數(shù)據(jù)中,有其他人更新了這一行,那么這一行也就不是你所需要的那一行了,為了防止這樣的沖突,所以把所有字段都放在WHERE語句中,這是by design的。

你可以通過其他方法進行更新數(shù)據(jù),然而在目前版本,這個方法也表現(xiàn)的不怎么樣。

System.Data.Linq.Table有一個Attach方法,帶有三個重載,用來直接更新數(shù)據(jù)的,我們來一個一個的來看看。

  1. Attach(T entity)  
  2. var ctx = new MyDataContext();  
  3. var newUser = new User();  
  4. newUser.UserId = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
  5. //假設(shè)作為參數(shù)傳進來的  
  6. newUser.UserName = "New User Name";  
  7. ctx.Users.Attach(newUser);  
  8. ctx.SubmitChanges();   
  9. //結(jié)束

運行完全沒有任何效果,SQL Profiler無任何記錄。

  1. Attach(T entity, T original)  
  2. var ctx = new MyDataContext();  
  3. var newUser = new User();  
  4. newUser.UserId = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
  5. //假設(shè)作為參數(shù)傳進來的  
  6. newUser.UserName = "New User Name";  
  7. var user = ctx.User.Where(u => u.UserId = newUser.UserId).Single();  
  8. ctx.Users.Attach(newUser, user);  
  9. ctx.SubmitChanges();   
  10.  //結(jié)束

運行時提示: Cannot add an entity with a key that is already in use.

  1. Attch(T entity, bool asmodified)  
  2. var ctx = new MyDataContext();  
  3. var newUser = new User();  
  4. newUser.UserId = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
  5. //假設(shè)作為參數(shù)傳進來的  
  6. newUser.UserName = "New User Name";  
  7. ctx.Users.Attach(newUser, true);  
  8. ctx.SubmitChanges();   
  9.  //結(jié)束

運行時提示:An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.

怎么辦?提示中說"declares a version member ",通常來說是指SQL SERVER中TimeStamp類型的字段,在你所需要更新的表中加上一個字段,并標記為TimeStamp就可以了。但是這樣做,對于我們來說仍然是個浪費,并且WHERE語句中仍然會出現(xiàn)TimeStamp的限制。

你還可以通過在字段上設(shè)置UpdateCheck.Never屬性來避免更新檢查,但是如果數(shù)據(jù)表更新、新增存儲過程,需要重新生成dbml的話,你需要手動重新設(shè)置一遍。

Linq更新數(shù)據(jù)甚至沒有一個類似Web引用中Update Web Reference的操作來讓你方便的在數(shù)據(jù)表更新后更新dbml,并且在這個版本都不會提供,你所能做的只有刪除原來的表,刷新Server Exploer,重新拖拽到dbml的設(shè)計視圖中,或者,寫個腳本,讓SQLMETAL來幫你完成這些。

結(jié)論:

Linq雖然做為一個查詢語言出現(xiàn),但是在數(shù)據(jù)更新方面也是做了不少工作的,尤其是一些CHECK的工作,但對于寫慣SQL的我們來說,還是很不習(xí)慣,甚至覺得,這些工作你不替我做才好呢。

在沒有更好解決辦法的前提下,在更新操作上,老老實實的寫SQL語句或者存儲過程應(yīng)該是個不壞的選擇。Linq更新數(shù)據(jù)只能望而觀之了。

【編輯推薦】

  1. LINQ動態(tài)查詢的實現(xiàn)淺析
  2. LINQ TO SQL動態(tài)修改表名稱的實現(xiàn)淺析
  3. LINQ To SQL的一點討論
  4. 淺析LINQ事務(wù)處理的實現(xiàn)
  5. 淺析DataSet和DataTable
責(zé)任編輯:阡陌 來源: 天極網(wǎng)
相關(guān)推薦

2024-11-11 14:45:34

2017-09-26 11:06:15

數(shù)據(jù)庫索引查詢

2012-05-01 07:42:41

蘋果

2015-03-06 09:47:53

小米變化

2009-06-15 17:32:09

LINQ更新數(shù)據(jù)

2020-04-20 13:48:21

大數(shù)據(jù)數(shù)據(jù)隱私AI

2021-09-04 23:33:32

996互聯(lián)網(wǎng)加班

2014-12-23 09:25:56

程序性能代碼

2021-08-30 15:41:13

Kafka運維數(shù)據(jù)

2019-08-27 08:24:17

簡歷技能工作

2016-06-01 15:42:58

Hadoop數(shù)據(jù)管理分布式

2021-07-02 21:07:35

負載均衡模型nginx

2020-04-17 14:25:22

Kubernetes應(yīng)用程序軟件開發(fā)

2013-07-15 16:55:45

2014-04-17 16:42:03

DevOps

2022-07-26 00:00:22

HTAP系統(tǒng)數(shù)據(jù)庫

2018-07-17 16:26:17

大數(shù)據(jù)營銷消費者

2023-11-07 07:36:58

JavaThis關(guān)鍵字

2009-05-08 10:15:04

LINQ插入刪除

2023-11-06 08:41:31

JavaScript應(yīng)用程序
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 精品国产一区二区国模嫣然 | 欧美aⅴ | 日韩毛片在线视频 | 99re热这里只有精品视频 | 国产精品久久久久久久久久久久冷 | 亚洲精品久久区二区三区蜜桃臀 | 国产精品久久 | 国产精品3区 | 日韩成人精品一区二区三区 | 欧美二区三区 | 欧美三区视频 | 久久久久无码国产精品一区 | 中文字幕av网 | 国产精品视频免费观看 | 国产精品一区二区久久久久 | 天天干天天玩天天操 | 在线免费看黄 | 精品免费视频一区二区 | 婷婷色国产偷v国产偷v小说 | 国产一区亚洲二区三区 | 国产成人精品免费视频大全最热 | 国产成人综合网 | 精品成人免费一区二区在线播放 | 99精品久久久久 | 日韩在线精品 | 亚洲一区视频在线 | 亚洲视频免费在线 | 欧美精品日韩精品国产精品 | 亚洲日本三级 | 国产亚洲精品美女久久久久久久久久 | 久久久久久国产 | 久国产视频 | 国产精品久久777777 | 手机av网| 欧美性大战久久久久久久蜜臀 | 成人av网站在线观看 | 色爱av | 婷婷久久精品一区二区 | 日韩成人免费 | 99热播放 | 亚洲精品一区二区在线观看 |