2016-05-31 27 views
1

私のプロジェクトでこれをやろうとしていますEntity Framework Databinding with WinForms シングルフォームの代わりに2つのフォームを使用しています。Entity Framework(マスター詳細)マスターから別のフォームにある詳細

CategoryDataGridViewForm1に表示され、その後、ProductsDataGridView(選択したカテゴリの製品リスト)を持っているのForm2をロードして、変更を保存するには、ボタンを救うForm1上の編集ボタンは、そこにある

私が持っています私のForm2上の次のコード

ProductContext _context = new ProductContext(); 
public int SeletedCategID { get; set; } 

private void Form2_Load(object sender, EventArgs e) 
{ 
    _context.Products.Where(c => c.CategoryId ==  SeletedCategID).ToList(); 
    productsBindingSource.DataSource =  (_context.Products.Local).ToList(); 
} 

private void SaveBtn_Click(object sender, EventArgs e) 
{ 
    this.Validate(); 

    foreach (var product in _context.Products.Local.ToList()) 
    { 
     if (product.Category == null) 
     { 
      _context.Products.Remove(product); 
     } 
    } 
    this._context.SaveChanges(); 

    this.productsDataGridView.Refresh(); 

    Form1 frm1 = (Form1)Application.OpenForms["Form1"]; 
    frm1.Activate(); 
    frm1.Refresh(); 
    this.Dispose(); 
} 

私の問題は現在、製品にのみ編集され、DBに保存されています。追加&削除はデータベースに保存されません。

+0

あなたは 'Form1'で何か変更を確認してもよろしいですか?私はそれが独自のキャッシュされたエンティティを持つ独自のコンテキストを持っていると仮定します。 –

答えて

2

context.Products.Local.ToList()を設定している間は、バインディングソースのデータソースとしてcontext.Products.Localを設定する必要があります。

context.Products.Localはコンテキストと同期しており、すべてのエンティティの変更(追加/削除/編集)はコンテキストによって追跡されます。ObservableCollection<Product>を取得します。
context.Products.Local.ToList()を使用すると、List<T>はコンテキストとの同期が保たれず、追加/削除は追跡されず、SaveChangesを呼び出すと、編集と保存は保存されません。

DbSet<TEntity>.Local すべて 追加、変更なし、そしてこのセットで変更されたエンティティのローカルビューを表しObservableCollection<T>を取得します。このローカルビュー は、エンティティがコンテキストに追加または削除されたときに同期状態を維持します。 同様に、ローカルビューに追加または削除されたエンティティは、 というコンテキストに自動的に追加または削除されます。

コード:

あなたはデータをこのようにロードできます。

context.Products.Where(x => x.CategoryId == SelectedCategoryId).ToList(); 
this.productBindingSource.DataSource = context.Products.Local; 

をそして、あなたはデータをこのように保存することができます:

this.Validate(); 
this.productBindingSource.EndEdit(); 
context.Products.Local 
     .Where(x => x.CategoryId == 0) 
     .ToList().ForEach(x => 
     { 
      x.CategoryId = SelectedCategoryId; 
     }); 
context.SaveChanges(); 
this.DialogResult = DialogResult.OK; 

またことを必要としませんマスターディテールを使用していないため、ヌルカテゴリの商品を削除するコードの一部です。編集可能なリストです。

もう1つのメモとして、2番目のフォームを閉じた後、最初のフォームでデータを再読み込みすることを忘れないでください。フォームで異なるコンテキストを使用しているため、他のコンテキストでの変更を認識していません。

+0

こんにちはReza、詳細な回答ありがとうございます。しかし、 'productBindingSource.DataSource'を' Products.Local'に設定しようとすると、編集と削除はDBに保存されますが、AddはDBに保存されず、 'DataGridViewデフォルトエラーダイアログ'エラーを表示しました。以下のメッセージが表示されます。 DataGridViewで次の例外が発生しました。 System.IndexOutOfRangeException:インデックス3に値がありません。 System.Windows.Forms.CurrencyManager.get_Item(Int32 index)、System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 rowIndex)で、7回表示されます。 – Henry

+1

おそらく、新しいレコードに有効な 'CategoryId'を設定しなかったからでしょう。変更を保存する代わりに 'CategoryId'カラムをグリッドに表示しないでください。すべての製品の' CategoryId'を 'SelectedCategoryId'に設定してください。 –

+0

解決策は私が言ったことです。テスト済みで正常に動作しています:) –

0

これは機能しません。ローカルではなく製品を削除する必要があります。

 foreach (var product in _context.Products.ToList()) 
     { 
      if (product.Category == null) 
      { 
       _context.Products.Remove(product); 
      } 
     } 
     this._context.SaveChanges(); 

あなたが唯一の地元削除する場合:

_context.Locals.Remove(local); 

は、私はあなたがロードオブジェクトリストで行っているが、変更または製品を削除してくださいしようとしている場合かわかりませんか、 DbContextで見つからないローカルエンティティまたはエンティティのコピーである場合、これは機能しません。元の検索エンティティが必要です。

関連する問題