DataGridView を編集可能にし、コンテキストの変更を追跡する方法で Entity Framework を使用してデータをフィルター処理する方法は?

DataGridView. フィルタを適用した場合でも編集可能です。

DbContext の単一インスタンスを使用する

DbContext の単一のインスタンスを使用する .変更を保存するときに新しいインスタンスを作成すると、新しいインスタンスは他のインスタンスで行った変更を認識できません。したがって、フォーム レベルで宣言します。

TestDBEntities db = new TestDBEntities();

データのロード - エンティティのローカル ストレージにバインド

接続モードでエンティティを操作する場合は、Load を使用してデータをロードします db.Products.Load() のような db set のメソッド または ToList を呼び出して db.Products.ToList() のように .

BindingSource をバインドします db.Products.Local.ToBindingList()まで .そのため、バインディング ソースに対して項目を追加または削除すると、変更トラッカーが変更を検出し、項目を追加および削除します。

ToBindingListを見るには 拡張メソッド add using System.Data.Entity; .

DataGridView で追加が有効になっている場合 、次にプロキシの作成をオフにして、フィルタリング時の例外を防ぎます。

db.Configuration.ProxyCreationEnabled = false;
db.Products.Load(); 
this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();

Linq を使用したデータのフィルタリング

データをフィルタリングするには、linq を使用します。 Filter は使用できません BindingSource のプロパティ 基になるリストが BindingList<T> の場合; IBindingListView を実装する基になるリストのみ インターフェイスはフィルタリングをサポートします。

フィルタリングを適用するには、linq を使用します。例:

var filteredData = db.Products.Local.ToBindingList()
    .Where(x => x.Name.Contains(this.FilterTextBox.Text));
this.productsBindingSource.DataSource = filteredData.Count() > 0 ?
    filteredData : filteredData.ToArray();

フィルタを削除

フィルターを削除するには、バインド ソースのデータ ソースをエンティティのローカル ストレージに再度設定します。このように、フィルタを削除すると、追加と削除が機能します。

this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();

追加/削除/編集

追加は、フィルタリングされていないモードでのみ機能します。ユーザーがエンティティを追加できるようにするには、フィルターを削除します。

編集は、フィルター処理されたモードまたはフィルター処理されていないモードの両方で機能します。

削除は、フィルタされたモードまたはフィルタされていないモードの両方で機能します。しかし、 BindingNavigator を使用すると フィルター モードでは、削除ボタンに頼ることはできません。フィルタリングされたモードとフィルタリングされていないモードの両方で機能させるには、DeleteItem を設定する必要があります。 BindingNavigator のプロパティ None まで アイテムの削除クリック イベントを処理し、独自のコードを記述します。

if (productsBindingSource.Current != null)
{
    var current = (Product)this.productsBindingSource.Current;
    this.productsBindingSource.RemoveCurrent();
    if (!string.IsNullOrEmpty(this.FilterTextBox.Text))
        db.Products.Local.Remove(current);
}

フォームの破棄時または終了時に DbContext を破棄

実際のアプリケーションでは、DbContext を破棄することを検討してください フォームの破棄または終了時:

db.Dispose();

サンプル コード

以下は、上で説明した内容を含むサンプル コードです。

using System.Data.Entity;
SampleDbEntities db = new SampleDbEntities();
private void Form1_Load(object sender, EventArgs e)
{
    db.Configuration.ProxyCreationEnabled = false;
    db.Products.Load();
    this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();
}
private void FilterButton_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(this.FilterTextBox.Text))
    {
        this.productsBindingSource.DataSource = db.Products.Local.ToBindingList();
    }
    else
    {
        var filteredData = db.Products.Local.ToBindingList()
            .Where(x => x.Name.Contains(this.FilterTextBox.Text));
        this.productsBindingSource.DataSource = filteredData.Count() > 0 ?
            filteredData : filteredData.ToArray();
    }
}
private void productBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
    this.Validate();
    productsBindingSource.EndEdit();
    db.SaveChanges();
}
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
{
    if (productsBindingSource.Current != null)
    {
        var current = (Product)this.productsBindingSource.Current;
        this.productsBindingSource.RemoveCurrent();
        if (!string.IsNullOrEmpty(this.FilterTextBox.Text))
            db.Products.Local.Remove(current);
    }
}