2011-06-20 85 views
2

我人的體育的連接表與下面的模式:LINQ到SQL查詢優化問題

PersonId 
SportID 

如何有效地設定人的運動在一個事務中即

void SetPersonsSports(List<PersonsSportsL> sports); 

我這樣做的方法是先用x.PersonId = PersonId刪除所有人的體育項目,然後再添加所有體育項目,但我知道刪除操作很昂貴,並且希望看到其他人在面對類似任務時正在做什麼。

謝謝。

UPDATE:

這裏就是我想....

void SetPersonsSports(List<PersonsSports> PersonSports) 
    { 

     using (DataContext dc = conn.GetContext()) 
     { 
      if (PersonSports.Select(x=>x.PersonID).Distinct().Count()>1) 
       throw new Exception("This method can only be used with a set of sports for the same person ID at a time"); 
      var sportIDs = PersonSports.Select(x=>x.SportID); 
      bool submitFlag = false;     
      var toRemove = dc.PersonSports.Where(x=>!sportIDs.Contains(x.SportID)); 
      if (toRemove.Count()>0) 
      { 
       dc.PersonSports.DeleteAllOnSubmit(toRemove); 
       submitFlag = true; 
      } 
      var toAdd = dc.PersonSports.Where(x=>!sportIDs.Contains(x.SportID)); 
      if (toAdd.Count()>0) 
      { 
       dc.PersonSports.InsertAllOnSubmit(toAdd); 
       submitFlag = true; 
      } 
      if (submitFlag) 
       dc.SubmitChanges(); 

     } 
    } 

回答

2

你的建議是完全正確的 - 有沒有真正一個更好的方式來做到這一點。

你有一個小錯誤/錯字

var toAdd = dc.PersonSports.Where(x=>!sportIDs.Contains(x.SportID)); 

這應該是(你應該使用方法參數駱駝)

var toAdd = PersonSports.Where(x=>!sportIDs.Contains(x.SportID)); 

我會成爲唯一的建議是考慮是否在執行任何數據庫插入和更新之前,您需要確定刪除哪些記錄&刪除。如果你的方法比這更復雜,你可能會遇到問題,因爲在枚舉之前集合可能會更改。我更喜歡確保我的收藏立即得到評估。

// just get the sport ids from the database here 
// rather than the entire PersonSport objects 
var toRemove = dc.PersonSports.Where(x=>!sportIDs.Contains(x.SportID)).ToList(); 
var toAdd = PersonSports.Where(x=>!sportIDs.Contains(x.SportID)).ToList(); 

if (toRemove.Any()) 
{ 
    dc.PersonSports.DeleteAllOnSubmit(toRemove);       
}    

if (toAdd.Any())    
{      
    dc.PersonSports.InsertAllOnSubmit(toAdd); 
} 

dc.SubmitChanges(); 

最後要注意,如果你有2100個多運動,因爲ID將作爲參數發送,這將打破,那就是對參數的最大數量的硬SQL限制。如果這是一個問題,您可以統計您正在使用的參數數量,並一次執行2000個參數。

+0

非常感謝您完成我的思考過程,並提供了一個完整的解決方案,其中包含極其重要的評論,尤其是關於2100參數限制的說明。再次感謝你。並且...我從來沒有使用任何()...這是一個很好的替代Count()> 0 +1 – alexm

+0

@alexm你非常歡迎! 「Any」運營商特別適合這種類型的任務,因爲它更高效。例如,如果一個集合中有10,000個項目,「Count」實際上必須計算所有項目,但「Any」運算符只需找到一個項目並停止查找。 –