Comment écrire un arbre d'expression générique pour filtrer les données en c #

c# entity-framework expression-trees

Question

Bonjour, je crée une application winform en c #.

J'utilise EF5 pour travailler avec une base de données.

et pour lier les données à mes datagridviews, j'ai créé un composant à partir de BindingSource qui possède une méthode Bind () qui exécute cet événement:

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

parce que ma base de données contient beaucoup de données volumineuses, je récupère une partie des données. et j'utilise la recherche pour obtenir une fiche de match. Pour cela, j'ai créé un composant SearchPanel qui crée des zones de texte pour filtrer chaque colonne de ma grille.

Je souhaite maintenant envoyer un arbre d’expression à mon événement en tant que paramètre à joindre à la clause where de la manière suivante:

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

mais ma méthode de création d'arborescence d'expression existe dans mon code de composant et je n'ai pas accès à mon DbContext dans mon projet et j'ai juste fieldNames dans mon composant, je souhaite également écrire une méthode pour toutes les tables.

cela signifie que je ne peux pas revenir comme

Expression <Func <AnyDbSet, bool >>

et je ne sais pas comment faire?

Merci

Réponse acceptée

Si vous avez juste besoin de && , il est utile de comprendre que coll.Where(x => a(x) && b(x)) (où a(x) et b(x) sont des expressions booléennes qui fonctionnent avec x ) est logiquement identique à coll.Where(x => a(x)).Where(x => b(x)) . Cela signifie que vous pouvez réécrire votre code comme suit:

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

Si vous avez également besoin de soutenir || ou des combinaisons plus compliquées, vous pouvez utiliser LINQKit .

Cela laisse simplement la question de la création de l'expression à partir d'un nom de propriété. Vous pouvez utiliser une méthode du type Expression pour cela. Par exemple, quelque chose comme:

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);
}

Réponse populaire

Je recommanderais d'utiliser le PredicateBuilder de Joseph Albahari. Vous pouvez le trouver à l' adresse http://www.albahari.com/nutshell/predicatebuilder.aspx .



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow