Eu estou fazendo uma consulta usando o linq para entidades e quero reutilizar o mesmo código, mas com uma instrução select ligeiramente diferente. Esta é a consulta:
return from f in GetFields<T>()
where f.Id == Id
select new Prop<V>
{
Name = f.Name,
Value = toValue(f.value)
};
onde toValue é um Func que cria um novo objeto Value. Eu quero usar várias funções toValue que possuem esse tipo de corpo:
var toValue = f => new DerivedValueClass {
FirstField = f.FirstField,
SecondField = f.SecondField
}
Portanto, é apenas uma atribuição simples, que será facilmente traduzida pelo sql para entidades. No entanto, quando eu executo o código, o linq para entidades afirma:
The LINQ expression node type "Invoke" is not supported in LINQ to Entities
Eu acho que não é possível chamar a função toValue, uma vez que não pode ser traduzido. Como posso criar uma expressão da função toValue para usá-la dentro da consulta linq?
Respostas:
0 para resposta № 1Eventualmente eu descubro que Linqkit permite fazer esse tipo de coisa com muita facilidade:
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
};
É realmente importante que toValue seja umExpressão, uma vez que o compilador criará um ExpressionTree em vez de simplesmente gerar uma expressão lambda. O Linqkit usa algum truque para substituir a chamada toValue por uma árvore de expressão. Mais informações sobre o site LinqKit e Aqui