日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
為你揭曉Linq更新數(shù)據(jù)是否真的實(shí)用?

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

站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到濠江網(wǎng)站設(shè)計(jì)與濠江網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋濠江地區(qū)。

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

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

那么做為一個(gè)查詢(xún)語(yǔ)言,Linq更新數(shù)據(jù)方面又是怎么表現(xiàn)的呢?通常來(lái)說(shuō)Linq的更新會(huì)以以下的方式出現(xiàn)(絕大部分教程中都是這么寫(xiě)的)

 
 
 
  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會(huì)為我們生成類(lèi)似一下的SQL語(yǔ)句

***步,查詢(xún)

 
 
 
  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會(huì)取出所有的字段,在user.UserName = "New User Name"的時(shí)候,記錄下UserName字段被更新過(guò)了,UPDATE時(shí)會(huì)只更新UserName,但是把之前所有字段的值放在WHERE語(yǔ)句里來(lái)做為條件。

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

拋開(kāi)效率問(wèn)題,接下來(lái)我們看另外一種更新數(shù)據(jù),有個(gè)某個(gè)字段記錄頁(yè)面被訪問(wèn)的次數(shù),平時(shí)我們會(huì)用

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

但是如果我們寫(xiě)下如下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ù)會(huì)怎么做呢?和上面一樣!取出所有字段,把View加一,用所有字段做為條件(包括Views),更新回去。

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

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

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

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

 
 
 
  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ù)傳進(jìn)來(lái)的
  6. newUser.UserName = "New User Name";
  7. ctx.Users.Attach(newUser);
  8. ctx.SubmitChanges(); 
  9. //結(jié)束

運(yùn)行完全沒(méi)有任何效果,SQL Profiler無(wú)任何記錄。

 
 
 
  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ù)傳進(jìn)來(lái)的
  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é)束

運(yùn)行時(shí)提示: 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ù)傳進(jìn)來(lái)的
  6. newUser.UserName = "New User Name";
  7. ctx.Users.Attach(newUser, true);
  8. ctx.SubmitChanges(); 
  9.  //結(jié)束

運(yùn)行時(shí)提示: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.

怎么辦?提示中說(shuō)"declares a version member ",通常來(lái)說(shuō)是指SQL SERVER中TimeStamp類(lèi)型的字段,在你所需要更新的表中加上一個(gè)字段,并標(biāo)記為T(mén)imeStamp就可以了。但是這樣做,對(duì)于我們來(lái)說(shuō)仍然是個(gè)浪費(fèi),并且WHERE語(yǔ)句中仍然會(huì)出現(xiàn)TimeStamp的限制。

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

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

結(jié)論:

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

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


網(wǎng)頁(yè)標(biāo)題:為你揭曉Linq更新數(shù)據(jù)是否真的實(shí)用?
文章出自:http://www.dlmjj.cn/article/cdjihod.html