Usando árboles de expresiones para crear un orden personalizado en linq para entidades

.net c# entity-framework expression-trees linq

Pregunta

Tengo una tabla que está asignada, pero después de compilar, se pueden agregar o eliminar columnas adicionales de la tabla. Estoy tratando de encontrar una consulta de linq que tenga en cuenta esas nuevas columnas. En este escenario, quiero ordenar por una de esas columnas dinámicas. Esto es lo que tengo hasta ahora.

var queryableData = dc.wf_task_ext_attributes.AsQueryable();
ParameterExpression pe = Expression.Parameter(typeof(DateTime), "ExtValue105");

// The next line is where it fails
MethodCallExpression orderByCallExpression = Expression.Call(
      typeof(Queryable),
       "OrderBy",
       new Type[] { queryableData.ElementType, queryableData.ElementType },
       queryableData.Expression,
       Expression.Lambda<Func<DateTime, DateTime>>(pe, new ParameterExpression[] { pe }));

IQueryable<string> results = queryableData.Provider.CreateQuery<string>
                         (orderByCallExpression);

Está fallando con el siguiente mensaje:

Ningún método genérico 'OrderBy' en el tipo 'System.Linq.Queryable' es compatible con los argumentos y argumentos de tipo suministrados. No se deben proporcionar argumentos de tipo si el método no es genérico.

¿Qué estoy haciendo mal?

Respuesta popular

Su código intenta crear algo como Queryable.OrderBy(queryableData.Expression, ExtValue105 => ExtValue105) . No tengo idea de por qué esperas que funcione.

Si entiendo su pregunta correctamente, necesita crear dinámicamente una expresión como attribute => attribute.ExtValue105 y luego puede usarla para llamar a OrderBy() .

El código podría tener un aspecto similar a este (asumiendo que queryableData es queryableData IQueryable<Attribute> ):

var parameter = Expression.Parameter(typeof(Attribute), "attribute");
var property = Expression.Property(parameter, "ExtValue105");
var lambda = Expression.Lambda(property, parameter);

IQueryable<Attribute> results =
    Queryable.OrderBy(queryableData, (dynamic)lambda);

Podría usar queryableData.Provider.CreateQuery() manualmente para evitar la llamada dynamic , pero eso sería más complicado.



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