2012-04-27 80 views
0

我在EF 4.3.1上調用entities.savechanges()時出現錯誤。我的數據庫是一個sql ce v4商店,我正在編碼mvvm模式。我有我的上下文的本地版本,我發送到一個可觀察的集合和修改等。這工作正常,當我調用savechanges()時,數據庫中沒有行存在的對象保持良好。當我重新加載應用程序時,對象被填充到我的列表框中,但是如果我添加另一個對象並調用savechanges(),我會收到一個錯誤,指出重複值無法插入到唯一索引中。dbset.local更新數據庫:重複值無法插入唯一索引

從我的理解這意味着上下文嘗試我的實體保存到數據存儲,但它似乎是增加我的不變原始對象以及新的。我認爲這會讓他們孤身一人,因爲他們的狀態不變。

private void Load() 
    { 
     entities.Properties.Include("Images").Load(); 
     PropertyList = new ObservableCollection<Property>(); 
     PropertyList = entities.Properties.Local;   

     //Sort the list (based on previous session stored in database) 
     var sortList = PropertyList.OrderBy(x => x.Sort).ToList(); 
     PropertyList.Clear(); 
     sortList.ForEach(PropertyList.Add); 

     propertyView = CollectionViewSource.GetDefaultView(PropertyList); 
     if (propertyView != null) propertyView.CurrentChanged += new System.EventHandler(propertyView_CurrentChanged);  


     private void NewProperty() 
    { 
     try 
     { 
      if (PropertyList != null) 
      {            
       Property p = new Property() 
        { 
         ID = Guid.NewGuid(), 
         AgentName = "Firstname Lastname", 
         Address = "00 Blank Street", 
         AuctioneerName = "Firstname Lastname", 
         SaleTitle = "Insert a sales title", 
         Price = 0, 
         NextBid = 0, 
         CurrentImage = null, 
         Status = "Auction Pending", 
         QuadVis = false, 
         StatVis = false, //Pause button visibility 
         Sort = PropertyList.Count + 1,        
        }; 

       PropertyList.Add(p); 
       SaveProperties(); 
      } 

     private void SaveProperties() 
    { 
     try 
     {    
      foreach (var image in entities.Images.Local.ToList()) 
      { 
       if (image.Property == null) 
        entities.Images.Remove(image); 
      }     
     } 

     catch (Exception ex) 
     { 
      System.Windows.MessageBox.Show(ex.Message); 
     } 

     entities.SaveChanges(); 
    } 

回答

1

沒有評論所有代碼在這裏,這是這是位導致你調出特定的問題:

//Sort the list (based on previous session stored in database) 
var sortList = PropertyList.OrderBy(x => x.Sort).ToList(); 
PropertyList.Clear(); 
sortList.ForEach(PropertyList.Add); 

此代碼:

  • 開始與已被查詢的和正在由上下文不變的實體跟蹤實體。也就是說,已知的實體已經存在於數據庫中。
  • 創建這些實體的新排序列表。
  • 調用清除本地集合,導致每個被跟蹤實體被標記爲刪除並從集合中刪除。
  • 將每個實體返回到上下文把它現在在加狀態意味着它是新的,當調用SaveChanges將被保存到數據庫中,

那麼有效,你告訴EF,所有的實體數據庫中存在的實際不存在並需要保存。所以它試圖做到這一點,它會導致你看到的異常。

爲了解決這個問題沒有明確的DbContext本地收集並添加實體回來。相反,您應該在視圖中使用本地集合對視圖進行排序。

+0

爲什麼我沒有看到這個!談論需要一套新的眼睛,當我回到這個下午時,會給它一個鏡頭。 – randomalbumtitle 2012-04-27 20:56:11

1

這聽起來就像是增加現有的實體上下文(這標誌着它們插入),而不是安裝它們(這標誌着他們與現有未修改)。

我也不能確定新的GUID()沒有返回相同的GUID ......我總是用Guid.NewGuid()http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx

+0

Guid's很好。從已保存到數據庫的對象中,我可以看到它們都有獨特的指導。我不完全理解如何使用附加功能,可能是因爲我從來沒有想過我會需要使用它。我認爲dbset.local的想法是能夠創建上下文的本地版本,以便我可以使用可觀察集合。無論什麼時候添加/刪除,本地都應該與上下文同步。當我調用保存更改時,上下文應與數據庫同步。這個想法是否正確?爲什麼上下文中不包含db中的現有對象? – randomalbumtitle 2012-04-27 05:58:07

+0

我認爲大部分你是正確的。當你創建一個上下文時,它基本上變成了一個越來越大的內存表現形式,你通過它從數據庫(附件)加載的實體以及添加到它的實體(添加)。它還跟蹤對這些實體的更改(已修改)並記住已從上下文中刪除的實體(已刪除)。調用SaveChanges()會導致上下文將實體的表示反映回數據庫 - (附加=忽略,增加=插入,修改=更新,刪除=刪除) – kroehre 2012-04-27 06:17:03

+0

只是讓我覺得這個實現將會拍攝記憶通過我的應用程序的屋頂。也許我最好在整個應用程序的整個過程中使用本地副本,然後一旦我準備好退出並保存,我就可以清除整個數據庫並將其加載到對象中。說實話,我對微軟並沒有留下深刻的印象 - 他們確實不會讓EF或WPF顯得那麼有吸引力。 – randomalbumtitle 2012-04-27 07:01:07