Come scrivere un albero di espressioni generico per filtrare i dati in c #

c# entity-framework expression-trees

Domanda

Ciao io creo un'applicazione winform in c #.

Io uso EF5 per lavorare con il database.

e per associare i dati ai miei datagridview ho creato un componente da BindingSource che ha un metodo Bind () che esegue questo evento:

private object bindingSourceTbl1_DataSourceBinding(object sender, EventArgs e)
{
    using (SampleDbEntities dbo = new SampleDbEntities())
    {
      return(from x in dbo.Tbl1
             where x.Id == (int)comboBoxPerson.SelectedValue
             select x).Take(1000).ToList();
    }
}

poiché il mio database ha molti dati di grandi dimensioni, recupero i dati parziali. e io uso la ricerca per ottenere il record della partita. per questo ho creato un componente SearchPanel che crea caselle di testo per filtrare ogni colonna nella mia griglia.

ora desidero inviare un albero di espressioni al mio evento come parametro per unire alla clausola where in questo modo:

private object bindingSourceTbl1_DataSourceBinding(object sender, EventArgs e,Expression whereClause)
{
    using (SampleDbEntities dbo = new SampleDbEntities())
    {
      return(from x in dbo.Tbl1
             where x.Id == (int)comboBoxPerson.SelectedValue && whereClause
             select x).Take(1000).ToList();
    }
}

ma il mio metodo tree builder espressione esiste nel mio codice componente e non accedo al mio DbContext nel mio progetto e ho solo fieldNames nel mio componente, inoltre voglio scrivere solo un metodo per tutte le tabelle.

questo significa che non posso tornare come

Espressione <Func <AnyDbSet, bool >>

e non so come si fa?

Grazie

Risposta accettata

Se hai bisogno solo di && , allora è utile rendersi conto che coll.Where(x => a(x) && b(x)) (dove a(x) b(x) sono espressioni booleane che funzionano con x ) è logicamente uguale a coll.Where(x => a(x)).Where(x => b(x)) . Ciò significa che puoi riscrivere il tuo codice per qualcosa di simile:

List<Tbl1Type> GetTbl1Values(Expression<Func<Tbl1Type, bool>> whereClause)
{
    using (SampleDbEntities dbo = new SampleDbEntities())
    {
        return dbo.Tbl1
            .Where(x => x.Id == (int)comboBoxPerson.SelectedValue)
            .Where(whereClause)
            .Take(1000).ToList();
    }
}

Se dovessi anche supportare || o combinazioni più complicate, potresti usare LINQKit .

Questo lascia solo il problema di creare l'espressione da un nome di proprietà. Puoi usare il metodo del tipo Expression per quello. Ad esempio, qualcosa come:

static Expression<Func<T, bool>> CreateWhereClause<T>(
    string propertyName, object propertyValue)
{
    var parameter = Expression.Parameter(typeof(T));
    return Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(parameter, propertyName),
            Expression.Constant(propertyValue)),
        parameter);
}

Risposta popolare

Consiglierei di usare PredicateBuilder di Joseph Albahari. Puoi trovarlo su http://www.albahari.com/nutshell/predicatebuilder.aspx .



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché