2011-09-19 57 views
0

一個保存()函數插入/更新我有一個街道表,其中有作爲的PK,是郵遞區號和streetcode兩個String列的組合。EF4.1的DbContext:在沒有身份PK

隨着EF4.1和的DbContext,我想編寫一個「保存」方法比採用一條街(即將在未附着狀態),檢查是否已經存在於數據庫中。如果這樣做,問題的最新情況,如果沒有,它會發出一個INSERT。

僅供參考,可以節省這些街道的應用,從文本文件閱讀他們,拯救他們(有沒有幾萬在該文件中,這些「streetlines」的)。

我想出現在是:

public void Save(Street street) 
    { 
     var existingStreet = (
           from s in streetContext.Streets 
           where s.PostalCode.Equals(street.PostalCode) 
           && s.StreetCode.Equals(street.StreetCode) 
           select s 
          ).FirstOrDefault(); 

     if (existingStreet != null) 
      this.streetContext.Entry(street).State = System.Data.EntityState.Modified; 
     else 
      this.streetContext.Entry(street).State = System.Data.EntityState.Added; 

     this.streetContext.SaveChanges(); 
    } 

這是很好的做法?這裏的表現如何?因爲每一條街道都會首先進行數據庫往返查看它是否存在。

嘗試插入街道(state = added)並捕獲任何PK違規行爲會不會更好?在catch塊,然後我可以改變狀態,以修改和()再次調用的SaveChanges。或者這不是一個好的做法?

有什麼建議?

感謝

回答

1

感謝您的答覆,但沒有人真的滿意,所以我做了一些更多的研究,並重寫了這樣的方法,這符合我的需要。

PS:改名的方法導入(),因爲我發現了一個用於(散裝)從外部導入的實體(如在我的情況下,文本文件)

PS2的方法更合適的名稱:我知道,最好的做法是趕上一個例外,讓它不做任何事情就默默地死去,但在我的特殊情況下,我沒有必要對它做任何事情。它只是作爲一種方法來發現該行已經存在於數據庫中。

public void Import(Street street) 
{ 
     try 
     { 
      this.streetContext.Entry(street).State = System.Data.EntityState.Added; 

      this.streetContext.SaveChanges(); 
     } 
     catch (System.Data.Entity.Infrastructure.DbUpdateException dbUex) 
     { 
      this.streetContext.Entry(street).State = System.Data.EntityState.Modified; 

      this.streetContext.SaveChanges(); 
     } 
     finally 
     { 
      ((IObjectContextAdapter)this.streetContext).ObjectContext.Detach(street); 
     } 
} 
1

選擇所有的街道,然後做一個對每個進行比較,並改變狀態循環。循環完成後調用saveChanges。通過這種方式,您只需撥打一些電話給db而不是幾個thousend

+0

謝謝,但不是真正的選擇,我認爲一次加載20K街道實體,性能明智 – tjeuten

0

如果街道已經存在於數據庫中,則您的代碼必須導致異常,因爲您將從上下文中加載它,之後您將嘗試附加另一個實例對同一個上下文實例使用相同的主鍵。

如果你真的要做到這一點使用此代碼來代替:

public void Save(Street street) 
{ 
    string postalCode = street.PostalCode; 
    string streetCode = steet.StreetCode; 
    bool existingStreet = streetContext.Streets.Any(s => 
          s.PostalCode == postalCode 
          && s.StreetCode = steetCode); 

    if (existingStreet) 
     streetContext.Entry(street).State = System.Data.EntityState.Modified; 
    else 
     streetContext.Entry(street).State = System.Data.EntityState.Added; 

    streetContext.SaveChanges(); 
} 

反正它仍然不高併發系統的可靠解決方案,因爲其他線程可以插入相同的街道之間你檢查及後續插件。