将新对象创建转换为linq到实体的linq表达式

本文关键字:linq 实体 表达式 转换 创建 新对象 对象 | 更新日期: 2023-09-27 18:10:41

我正在使用linq对实体进行查询,我想重用相同的代码,但使用略有不同的选择语句。这是查询:

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

,其中toValue是一个创建新Value对象的Func。我想使用几个toValue函数,它们有这样的主体:

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

所以它只是一个简单的赋值,它将很容易被sql转换为实体。然而,当我执行代码时,linq到实体状态:

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

我猜这是不可能调用toValue函数,因为它不能被翻译。我如何从函数toValue创建一个表达式,以便在linq查询中使用它?

将新对象创建转换为linq到实体的linq表达式

最后我发现Linqkit允许很容易地做这类事情:

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

toValue是一个表达式是非常重要的,因为编译器将创建一个ExpressionTree而不是简单地生成一个lambda表达式。为了用表达式树代替toValue调用,Linqkit使用了一些技巧。更多关于LinqKit网站的信息,请点击这里