2012-04-27 24 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); 

このコード:照会されていると変更されていない実体としてコンテキストによって追跡されている事業体と

  • 開始。つまり、すでにデータベースに存在することが分かっているエンティティです。
  • これらのエンティティの新しい並べ替えリストを作成します。
  • ローカルコレクションでクリアされると、各追跡対象エンティティは削除済みとしてマークされ、コレクションから削除されます。
  • はあなたがEFを語っているので効果的に、それは新しく、SaveChangesメソッドが呼び出されたときにデータベースに保存されることを意味しますが追加されました状態になりました

それを置くコンテキストに戻って各エンティティを追加しているすべてのエンティティ実際には存在しないため、保存する必要があります。したがって、これを実行しようとすると、例外が表示されます。

これを修正するには、DbContextローカルコレクションをクリアしてエンティティを追加しないでください。その代わりに、ローカルコレクションを使用してビューをソートして、ビューを元に戻す必要があります。

+0

なぜ私はこれを見ませんでした!新鮮な目を必要とすることについて話し、私がこの午後に戻ったときにそれを撃つでしょう。 – randomalbumtitle

1

あなたが(未修飾既存として、それらをマークしている)の代わりに、それらを結合させる(挿入のためにそれらをマーク)コンテキストに既存のエンティティを追加しているように聞こえます。

私はまた、新しいGUID()が同じGUIDを返していないことをわからないんだけど...私は常にすべてのコードにコメントがないとGuid.NewGuid()http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx

+0

Guid'sは問題ありません。データベースに保存されたオブジェクトから、それらのオブジェクトにはすべて固有のガイドがあることがわかります。おそらく私はそれを使う必要はないと思ったので、私はアタッチ機能の使い方を完全には理解していません。私は、dbset.localのアイデアは、観測可能なコレクションで作業できるように、コンテキストのローカルバージョンを作成できると考えました。何かが追加/削除されたときはいつでも、ローカルはコンテキストと同期する必要があります。変更の保存を呼び出すと、コンテキストはデータベースと同期する必要があります。このアイデアは正しいですか?コンテキストにdb内の既存のオブジェクトが含まれていないのはなぜですか? – randomalbumtitle

+0

あなたは大部分が正しいと思います。コンテキストを作成すると、基本的には、db(添付)および追加したエンティティ(追加)からロードするエンティティのメモリ内表現が増加します。また、これらのエンティティへの変更(変更)やコンテキストから削除したエンティティ(削除済み)を覚えています。SaveChanges()を呼び出すと、コンテキストにエンティティの表現がデータベースに反映されます。(添付=無視、追加=挿入、変更=更新、削除=削除) – kroehre

+0

この実装では、私のアプリケーションの屋根を介してメモリ。たぶん私は、アプリケーション全体の間、ローカルコピーで作業している方が良いでしょう。そして、いったん終了して保存する準備ができたら、データベース全体をクリアしてオブジェクトでロードすることができます。正に言えば、私はマイクロソフトには感銘を受けていません。彼らはEFやWPFを本当に魅力的なものにしません。 – randomalbumtitle

関連する問題