在entity framework查询的选择子句中使用函数

我想针对entity framework实现以下逻辑。

var items = from item in myContext select new { Value1 = TweakValue(item.Value1), Value2 = TweakValue(item.Value2) }; protected int TweakValue(int value) { // Custom processing here return value; } 

由于在select子句中调用TweakValue() ,因此无法工作。 我知道查询转换为SQL,问题是TweakValue()无法转换为SQL。 我的问题是实现这一目标的最经济的方法是什么。 我需要第二个循环来转换值吗?

我仍然试图熟悉LINQ表达式。

最简单的方法可能是将执行“移动”到客户端以执行转换。 在这种情况下,你只需使用:

 var items = myContext.Select(item => new { item.Value1, item.Value2 }) .AsEnumerable() .Select(item => new { Value1 = TweakValue(item.Value1), Value2 = TweakValue(item.Value2) }); 

请注意,您不必重用Value1Value2的名称 – 这是最简单的方法。

如果您真的想使用查询表达式:

 var query = from item in myContext select new { item.Value1, item.Value2 }; var items = from item in query.AsEnumerable() select new { Value1 = TweakValue(item.Value1), Value2 = TweakValue(item.Value2) }; 

如果要首先执行过滤,可以通过在调用AsEnumerable()之前进行过滤,排序等来在数据库中进行过滤。 例如:

 var query = from item in myContext where item.Foo == bar orderby item.Something select new { item.Value1, item.Value2 }; var items = from item in query.AsEnumerable() select new { Value1 = TweakValue(item.Value1), Value2 = TweakValue(item.Value2) }; 

你不需要循环,只需要另一个投影:

 var items = myContext.Select(i => new { Value1 = item.Value1, Value2 = item.Value2 }) .AsEnumerable() .Select(i => new { Value1 = TweakValue(item.Value1), Value2 = TweakValue(item.Value2) }); 

编辑:根据TweakValue实际执行的操作,您可以将整个操作推送到服务器。 重复你当前的例子:

 public Expression> TweakValue() { return item => new ItemProjection { Value1 = item.Value1, Value2 = item.Value2 + 0 // or something else L2E can understand... }; } 

现在使用它像:

 var exp = TweakValue(); var items = myContext.Select(exp); 

注意我将exp存储在一个变量中,这样L2E就不会尝试在查询中直接调用TweakValue ,这会失败。

当然,这只有在TweakValue执行L2E可以执行的操作时才有效。