Como filtrar os dados usando a plataforma de entidade de uma forma que a DataGridView seja editável e as alterações da faixa de contexto?

estou a usar a aplicação C# Windows Form para preencher dados da tabela de bases de dados sql server usando o Entity Framework (EFWinForms) usando o seguinte código:

MyEntityDataModel db = new MyEntityDataModel();
MyEDS = new EntityDataSource();
MyEDS.DbContext = db;
MyDataGridView.DataSource = MyEDS;
MyDataGridView.DataMember = "MyTable";
Funciona bem. Quando o utilizador editar, adicione dados; os dados podem ser gravados usando o seguinte código:

MyEDS.SaveChanges();

quero uma forma de filtrar estes dados através da fonte de dados da entidade para que a MyDataGridView permaneça editável e qualquer actualização feita pelo Utilizador em dados filtrados possa ainda ser gravada de volta à base de dados. Nota: ao usar o linq para entidade para filtrar dados funciona muito bem, mas ele apenas povoar um instantâneo de dados que não pode ser editado ou atualizado pelo Usuário novamente.

Author: Reza Aghaei, 2016-03-14

2 answers

Existem alguns pontos importantes que você deve considerar quando você quer trabalhar com a estrutura de entidade em formulários windows no modo conectado. Então você pode salvar as alterações corretamente.

Use uma única instância do seu DbContext

Utilize uma única instância do seu DbContext. Se você criar uma nova instância ao Salvar alterações, a nova instância não pode ver nenhuma alteração que você fez em outra instância. Declara-o ao nível do formulário:

TestDBEntities db = new TestDBEntities();

Carregar Os Dados-Ligar A Armazenamento Local de entidades

Quando você trabalha com entidades em modo conectado, primeira carga de dados usando db.Products.ToList() ou {[8] } em seguida, ligar o seu BindingSource a db.Products.Local.ToBindingList().
Liga a grade diretamente ao conjunto de entidades. Por isso, se adicionar ou remover do código de ligação, mude o localizador detecta as alterações e adiciona e remove os itens para si. Você pode carregar dados desta forma:

//using System.Data.Entity;
db.Configuration.ProxyCreationEnabled = false;
db.Products.Load(); // or db.Products.ToList();
this.productBindingSource.DataSource = db.Products.Local.ToBindingList();

Filtrar Os Dados Usando O Linq

Para filtrar os dados, use o linq. Não pode utilizar Filter propriedade de BindingSource Quando a a lista subjacente é BindingList<T>; apenas as listas subjacentes que implementam a filtragem de suporte da interface IBindingListView. Por exemplo, pode filtrar os dados desta forma:

var filteredData = db.Products.Local
                     .Where(x => x.Name.Contains(this.FilterTextBox.Text));
this.productBindingSource.DataSource = filteredData;

Remover O Filtro

Para remover o filtro, basta definir a fonte de dados da sua fonte de ligação para o armazenamento local das suas entidades novamente. Desta forma, adicionar e remover irá funcionar quando você remover o filtro.

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

Adicionar/Remover/Editar

A adição só funcionará em modo não filtrado. Para deixar o utilizador adicionar entidades, Remover filtro. podes fazê-lo funcionar, mas é razoável não lhe tocares.

A edição funcionará tanto em modo filtrado como em modo não filtrado.

A remoção pode funcionar tanto no modo filtrado como no modo não filtrado. Mas se você usar BindingNavigator Você não pode confiar no seu botão Apagar e você deve definir o seu DeleteItem nenhum e lidar com o seu item apagar carregue em evento e escreva o seu próprio código:

db.Products.Local.Remove((Product)this.productBindingSource.Current);
this.productBindingSource.RemoveCurrent(); 

Código Da Amostra:

Abaixo está um código de amostra que contém o que eu descrevi acima.

using System.Data.Entity;
//...

TestDBEntities db = new TestDBEntities();
private void Form1_Load(object sender, EventArgs e)
{
    db.Configuration.ProxyCreationEnabled = false;
    db.Products.ToList();
    this.productBindingSource.DataSource = db.Products.Local.ToBindingList();
}

private void FilterButton_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(this.FilterTextBox.Text))
    {
        this.productBindingSource.DataSource = db.Products.Local.ToBindingList();
    }
    else
    {
        var filteredData = db.Products.Local
                             .Where(x => x.Name.Contains(this.FilterTextBox.Text));
        this.productBindingSource.DataSource = filteredData;
    }
}

private void productBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
    db.SaveChanges();
}

private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
{
    db.Products.Local.Remove((Product)this.productBindingSource.Current);
    this.productBindingSource.RemoveCurrent();
}
 12
Author: Reza Aghaei, 2017-09-08 11:07:04

Embora não tenha a certeza do seu possível uso, geralmente USO a propriedade do filtro numa fonte de ligação para seleccionar certos registos sem desistir da capacidade de actualizar a base de dados. Algo do género:

        // Grab search string from SearchBox
        string strSearch = Convert.ToString(RichSearchBox.Text);

        // Apply Filter to BindingSource
        tblContactsBindingSource.Filter = "FileAs LIKE '*" + strSearch + "*'";

Utilize então a fonte de ligação como a fonte de dados para a área da grelha de dados:

        // Bind DataGridView to BindingSource
        recipientGridView.DataSource = tblContactsBindingSource;
 -1
Author: DWR C Sharper, 2016-03-13 23:44:56