Utilisation d'arbres d'expression pour créer un ordre personnalisé dans linq aux entités

.net c# entity-framework expression-trees linq

Question

J'ai une table qui est mappée, mais après la compilation, des colonnes supplémentaires peuvent être ajoutées ou supprimées de la table. J'essaie de créer une requête linq qui tiendra compte de ces nouvelles colonnes. Dans ce scénario, je souhaite commander par l'une de ces colonnes dynamiques. C'est ce que j'ai jusqu'ici.

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

Il échoue avec le message suivant:

Aucune méthode générique 'OrderBy' sur le type 'System.Linq.Queryable' n'est compatible avec les arguments de type fournis. Aucun argument de type ne doit être fourni si la méthode est non générique.

Qu'est-ce que je fais mal?

Réponse populaire

Votre code essaie de créer quelque chose comme Queryable.OrderBy(queryableData.Expression, ExtValue105 => ExtValue105) . Je ne sais pas pourquoi vous vous attendriez à ce que cela fonctionne.

Si je comprends bien votre question, vous devez créer dynamiquement une expression telle que attribute => attribute.ExtValue105 et vous pouvez ensuite l'utiliser pour appeler OrderBy() .

Le code pourrait ressembler à ceci (en supposant que queryableData est 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);

Vous pouvez utiliser queryableData.Provider.CreateQuery() manuellement pour éviter l'appel dynamic , mais ce serait plus compliqué.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi