2016-03-13 84 views
7

che sto usando C# Windows Form Applicazione per popolare i dati dalla tabella del database di SQL Server utilizzando Entity Framework (EFWinForms) utilizzando il seguente codice:Come filtrare i dati utilizzando Entity Framework in modo che DataGridView sia modificabile e la traccia di contesto cambi?

MyEntityDataModel db = new MyEntityDataModel(); 
MyEDS = new EntityDataSource(); 
MyEDS.DbContext = db; 
MyDataGridView.DataSource = MyEDS; 
MyDataGridView.DataMember = "MyTable"; 

Funziona benissimo. Quando l'utente modifica, aggiunge dati; i dati possono essere salvati utilizzando il seguente codice:

MyEDS.SaveChanges(); 

Voglio un modo per filtrare questi dati throug fonte Entity Data in modo che MyDataGridView rimane modificabile e qualsiasi aggiornamento fatto da utente a dati filtrati può ancora essere salvata di nuovo database. Nota: quando si utilizza linq su entità per filtrare i dati, funziona in modo ottimale ma popola solo un'istantanea di dati che non possono essere modificati o aggiornati dall'utente.

+1

Dipende dal modo in cui si carica, si associa e si filtrano i dati. –

risposta

12

Ci sono alcuni punti importanti che si dovrebbero prendere in considerazione quando si vuole lavorare con Entity Framework in Windows Form in modalità connessa. Quindi puoi salvare le modifiche correttamente.

utilizzare una singola istanza del DbContext

Utilizzare una singola istanza del vostro DbContext. Se si crea una nuova istanza al salvataggio delle modifiche, la nuova istanza non può vedere alcuna modifica apportata su un'altra istanza. Così dichiararlo a livello modulo:

TestDBEntities db = new TestDBEntities(); 

Carica dati - Bind allo stoccaggio locale degli Enti

Quando si lavora con Enti in modalità connessa, dati primo carico utilizzando db.Products.ToList() o db.Products.Load() quindi associare il tuo BindingSource a db.Products.Local.ToBindingList().
Associa la griglia direttamente al set di entità. Pertanto, se aggiungi o rimuovi dall'origine dell'associazione, il tracker rileva le modifiche e aggiunge e rimuove gli elementi per te. È possibile caricare i dati in questo modo:

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

Filtra dati utilizzando LINQ

Per filtrare i dati, utilizzare LINQ. Non è possibile utilizzare la proprietà Filter di BindingSource quando l'elenco sottostante è BindingList<T>; Solo gli elenchi sottostanti che implementano il filtro di supporto dell'interfaccia IBindingListView. Ad esempio è possibile filtrare i dati in questo modo:

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

Rimuovi Filtro

Per rimuovere il filtro, è sufficiente impostare di nuovo l'origine dei dati della vostra fonte vincolante per la memorizzazione locale delle vostre entità. In questo modo, l'aggiunta e la rimozione funzioneranno quando si rimuove il filtro.

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

Aggiungi/Rimuovi/Modifica

Add funzionerà solo in modalità non filtrato. Per consentire all'utente di aggiungere entità, rimuovere il filtro. puoi farlo funzionare ma è ragionevole non toccarlo.

La modifica funzionerà sia in modalità filtrata che non filtrata.

La rimozione può funzionare sia in modalità filtrata che non filtrata. Ma se si utilizza BindingNavigator non si può fare affidamento sul suo tasto di cancellazione e si dovrebbe impostare la sua DeleteItem senza nessuno e gestire la sua eliminazione evento elemento clic e scrivere il proprio codice:

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

codice di esempio:

Di seguito è riportato un codice di esempio che contiene ciò che ho descritto sopra.

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(); 
} 
+0

Ottima risposta. Funziona come un incantesimo esattamente come volevo. Manyyy thanks :) – EgyEast

+0

In questo modo, utilizzare Seleziona per colonne specifiche come: this.productBindingSource.DataSource = db.Products.Local.Select (new {columns ....}). ToBindingList(); ? – EgyEast

+1

No. Non è possibile modificare automaticamente i modelli non entità. È come quando si scrive un'istruzione select, ad esempio 'SELECT c1, c2 FROM t1', quindi il risultato non è aggiornabile e per l'aggiornamento è necessario associare manualmente le colonne alle colonne del database. Qui devi mappare quelle proprietà alle tue entità originali. –

-1

Anche se non sono sicuro del vostro possibile utilizzo, generalmente utilizzo la proprietà filtro su un'origine di associazione per selezionare determinati record senza rinunciare alla possibilità di aggiornare il database. Qualcosa di simile a questo:

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

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

quindi utilizzare il Fonte Binding come origine dati per la vista griglia di dati:

 // Bind DataGridView to BindingSource 
     recipientGridView.DataSource = tblContactsBindingSource; 
+0

Come potrei usare l'origine vincolante con Entity Framework nell'applicazione WinForms ?? – EgyEast

+0

Non ho senso negarlo. Non ho letto abbastanza bene la tua domanda. Mi dispiace per la mancanza. –