Cómo escribir un árbol de expresión genérico para filtrar datos en c #

c# entity-framework expression-trees

Pregunta

Hola, creo una aplicación winform en c #.

Yo uso EF5 para trabajar con la base de datos.

y para enlazar datos a mis vistas de datos, creé un componente de BindingSource que tiene un método Bind () que ejecuta este 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();
    }
}

Porque mi base de datos tiene muchos datos grandes, obtengo parte de los datos. y yo uso la búsqueda para obtener registro de coincidencia. para esto creé un componente SearchPanel que crea cuadros de texto para filtrar cada columna en mi cuadrícula.

en este momento quiero enviar un árbol de expresiones a mi evento como un parámetro para unir a la cláusula where como esta:

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

pero mi método de generador de expresiones existe en mi código de componente y no accedo a mi DbContext en mi proyecto y solo tengo nombres de campo en mi componente, también quiero escribir un solo método para todas las tablas.

esto significa que no puedo volver como

Expresión <Func <AnyDbSet, bool >>

y no se como hacerlo

Gracias

Respuesta aceptada

Si solo necesita && , entonces es útil darse cuenta de que coll.Where(x => a(x) && b(x)) (donde a(x) y b(x) son expresiones booleanas que funcionan con x ) es lógicamente lo mismo que coll.Where(x => a(x)).Where(x => b(x)) . Lo que esto significa es que puedes reescribir tu código a algo como:

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 también necesitabas apoyar || o combinaciones más complicadas, podrías usar LINQKit .

Esto solo deja la cuestión de crear la expresión a partir de un nombre de propiedad. Puedes usar el método del tipo de Expression para eso. Por ejemplo, algo como:

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

Respuesta popular

Recomendaría usar el PredicateBuilder de Joseph Albahari. Puede encontrarlo en http://www.albahari.com/nutshell/predicatebuilder.aspx .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow