Déplacement de la fonction C # vers une expression à utiliser dans Entity Framework / SQL Select

c# entity-framework expression expression-trees sql-server

Question

J'ai quelques petites fonctions C # et des colonnes calculées à partir de vues que j'aimerais déplacer vers Expressions afin qu'elles s'exécutent directement sur la source de données en T / SQL natif.

Je peux le faire en ligne dans la sélection, mais j'aimerais passer à une fonction commune pour la réutilisation et les tests.

var results = context
    .Products
    .Select(p => new StockDto
    {
        Stock = p.GoodStock - p.LiveStock // Real version is more complex.
    });

J'ai essayé de créer une fonction qui retourne une expression, mais C # tente d'assigner l'expression à la place du résultat de l'expression et ne compile pas. L'utilisation de la variable d'expression suivante ne compile pas non plus.

var results = context
    .Products
    .Select(p => new StockDto
    {
        Stock = p.GoodStock - p.LiveStock // Real version is more complex.
    });

Je connais bien l’utilisation d’expressions pour l’ajout aux clauses Where, mais je ne sais pas comment créer une expression qui retourne une chaîne à partir d’une instruction select.

J'aimerais faire ça;

var results = context
    .Products
    .Select(p => new StockDto
    {
        Stock = p.GoodStock - p.LiveStock // Real version is more complex.
    });

LinqKit semble avoir pour objectif de faciliter l'utilisation des prédicats (clauses Where), je ne vois pas comment compiler un arbre d'expressions. Est-ce que la seule façon de faire cela est de coder à la main un arbre d’expression complexe (j’aimerais éviter cela car cela obscurcit la signification du code)?

Réponse acceptée

LinqKit devrait fonctionner pour vous. Vous devriez appeler Invoke pour utiliser une expression dans une autre.

Vous avez deux options pour "développer" les expressions fusionnées:

Vous devez soit appeler AsExpandable sur IQueryable pour qu'il "développe" les expressions automatiquement comme ceci:

var results = context
    .Products
    .AsExpandable()
    .Select(p => new StockDto
    {
        Stock = StockLevel.Invoke(p) 
    });

Ou vous développez l'expression manuellement avant de l'utiliser comme ceci:

var results = context
    .Products
    .AsExpandable()
    .Select(p => new StockDto
    {
        Stock = StockLevel.Invoke(p) 
    });

Réponse populaire

Regardez Microsoft.Linq.Translations . Il vous permet de définir des propriétés avec des arbres d'expression, puis de les utiliser dans des requêtes. Pour la réutilisation de sélection, en effet LinqKit est votre ami, ou consulter cette réponse, si vous voulez vraiment comprendre comment cela fonctionne :)




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