/ / Convertir la création d'un nouvel objet en expression linq pour linq en entités - c #, linq, entity-framework, lambda, expression

Convertir la création d'un nouvel objet en expression linq pour linq en entités - c #, linq, entity-framework, lambda, expression

Je fais une requête en utilisant linq aux entités et je veux réutiliser le même code mais avec une instruction select légèrement différente. C'est la requête:

return from f in GetFields<T>()
where f.Id == Id
select new Prop<V>
{
Name = f.Name,
Value = toValue(f.value)
};

où toValue est un Func qui crée un nouvel objet Value. Je veux utiliser plusieurs fonctions toValue qui ont ce genre de corps:

var toValue = f => new DerivedValueClass {
FirstField = f.FirstField,
SecondField = f.SecondField
}

Il s’agit donc d’une simple affectation, qui sera facilement traduite par sql en entités. Cependant, lorsque j'exécute le code, linq to entity indique:

The LINQ expression node type "Invoke" is not supported in LINQ to Entities

Je suppose qu’il n’est pas possible d’appeler la fonction toValue, car elle ne peut pas être traduite. Comment créer une expression à partir de la fonction toValue afin de l’utiliser dans la requête linq?

Réponses:

0 pour la réponse № 1

Finalement, je découvre que Linqkit permet de faire ce genre de choses très facilement:

Expression<Func<T, V>> toValue =  a => new DerivedObject() {
// perform assignment here
}

return from f in GetFields<T>().AsExpandable() // <- LinqKit AsExpandable() extension method
where f.Id == Id
select new Prop<V>
{
Name = f.Name,
Value = toValue.Invoke(f.value) // <- LinqKit Invoke() extension method
};

Il est vraiment important que toValue soit unExpression, car le compilateur créera un ExpressionTree au lieu de générer simplement une expression lambda. Linqkit utilise une astuce afin de remplacer l'invocation toValue par un arbre d'expression. Plus d'infos sur le site LinqKit et ici