Entity Framework exécute une requête avec des propriétés non mappées. Arbre d'expression

c# entity-framework expression-trees linq

Question

Je veux exécuter la méthode linq sur iqueryable avec une arborescence d’expression de la fonction où je passe le nom de la méthode linq et le nom de la propriété Mais mon exemple de méthode ne fonctionne qu'avec des propriétés mappées. Il lève une exception lorsque j'essaie, par exemple, de trouver le maximum de propriétés calculées.

Mes classes:

    public partial class Something
    {
        public int a { get; set; }
        public int b { get; set; }
    }

    public partial class Something
    {
        public int calculated { get { return a * b; } }
    }

Méthode d'échantillon:

    public partial class Something
    {
        public int a { get; set; }
        public int b { get; set; }
    }

    public partial class Something
    {
        public int calculated { get { return a * b; } }
    }

Réponse acceptée

Pour pouvoir interroger des propriétés calculées, vous avez au moins 2 options:

1) vous stockez les valeurs calculées dans la base de données avec les lignes (ou dans une autre table) et les utilisez dans vos requêtes; bien sûr, cela nécessite un changement de modèle de données et une redondance des données, mais constitue le moyen le plus performant. Mais n’est-ce pas excitant, passons donc à

2) vous devez être capable d'exprimer la façon dont vous "calculez" les propriétés d'une manière que SQL comprendra, ce qui signifie que la propriété doit être remplacée par une expression linq dans la requête finale. J'ai trouvé en 2009 un article étonnant d'Eric Lippert sur l'enregistrement de telles propriétés en ligne, mais je ne le trouve plus. En tant que tel, voici un lien vers un autre, qui a la même idée. En gros, vous définissez votre calcul sous forme d'arborescence d'expression et utilisez la version compilée dans votre code.

Pour le rendre plus pratique, attribuez à votre propriété un

[AttributeUsage(AttributeTargets.Property)]
class CalculatedByAttribute: Attribute
{
    public string StaticMethodName {get; private set;}
    public CalculatedByAttribute(string staticMethodName)
    {
        StaticMethodName = staticMethodName;
    }
}

Comme:

[AttributeUsage(AttributeTargets.Property)]
class CalculatedByAttribute: Attribute
{
    public string StaticMethodName {get; private set;}
    public CalculatedByAttribute(string staticMethodName)
    {
        StaticMethodName = staticMethodName;
    }
}

(bien sûr, vous pouvez mettre en cache la compilation) :)

Ensuite, dans votre méthode, si la propriété a votre attribut, vous obtenez la valeur de la propriété statique et vous l'utilisez dans vos requêtes. Quelque chose de long:

[AttributeUsage(AttributeTargets.Property)]
class CalculatedByAttribute: Attribute
{
    public string StaticMethodName {get; private set;}
    public CalculatedByAttribute(string staticMethodName)
    {
        StaticMethodName = staticMethodName;
    }
}



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