在实体框架查询的选择子句中使用函数
本文关键字:函数 子句 选择 实体 框架 查询 | 更新日期: 2023-09-27 17:59:59
我想针对实体框架实现以下逻辑。
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)
});
请注意,您不需要来重用Value1
和Value2
的名称,这是最容易做到的
如果您真的想使用查询表达式:
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
实际执行的操作,您可以将整个操作推送到服务器。在你当前的例子上Riffing:
public Expression<Func<Item, ItemProjection>> 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可以做的事情时,这才有效。