如何使用EF查询中的函数参数化选择器?

时间:2016-08-04 11:43:29

标签: c# entity-framework linq entity-framework-6 expression-trees

我有一个投影函数,我传递给IQueryable<>.Select()方法:

private static Expression<Func<VendorPrice, PriceItem>> GetPriceSelector(){
    return e => new PriceItem {
        Id = e.Id,
        Price = Math.Round(e.Price, 4)
    };
}

一切正常,但我想将其参数化为:

private static Expression<Func<VendorPrice, PriceItem>> GetPriceSelector(Func<VendorPrice, decimal> formula){
    return e => new PriceItem {
        Id = e.Id,
        Price = formula(e)
    };
}

所以我可以像

一样调用它
prices.Select(GetPriceSelector(e => Math.Round(e.Price, 4)))

不幸的是,EF抱怨它:

  

LINQ to不支持LINQ表达式节点类型'Invoke'   实体

如何重写代码以使EF快乐?

1 个答案:

答案 0 :(得分:2)

首先,return Observable .interval(2000) // time in ms .flatMap(() => { return nextNumber() }); 方法需要接受表达式,而不是函数。区别在于表达式是代码作为数据,因此可以转换为SQL,而函数是编译代码,因此无法转换为SQL。

接下来,您需要一种合并两个表达式的方法。手动执行此操作很难。幸运的是,有一个名为LINQKit的库可以做到这一点。以下是使用LINQKit解决问题的方法:

GetPriceSelector