据我所知,如果linq查询中有一些函数没有映射到sql查询,那么你必须首先调用.AsEnumerable():
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.Select(data => new { Foo = CalculateFoo(data.Bar); });
不能由linq执行到sql,但是通过添加AsEnumerable(),我们可以使.select()子句由linq执行到对象:
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.AsEnumerable()
.Select(data => new { Foo = CalculateFoo(data.Bar); });
但是,如果数据集非常大,那么AsEnumerable对分页有什么影响呢?如果我说:
var page = model.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows);
因为model现在是IEnumerable而不是IQueryable,当我们说model.Skip()。Take()时,它是否必须首先从数据库加载整个数据集才能跳过并取走? (这会破坏传呼的目的)
编辑:这个问题一般是写的 - 这些都是具体的细节:
我无法控制分页。我正在生成一个模型并将其传递给网格组件(在这种情况下为DevExpress,但可以是任何网格)。发出分页命令的是网格组件。涉及使用.Skip()的任何解决方案。在此之前无法使用AsEnumerable()之前的Take()。
所以我需要能够将此模型传递给网格,同时确保模型使用延迟执行:
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.Select(data => new {
data.Id,
data.Customer.Code,
data.Customer.Name,
// etc, select a few other properties
Foo = CalculateFoo(data.Bar);
});
所以现在我有一个摇滚与硬地问题:
答案 0 :(得分:1)
只需在Skip/Take
之前致电AsEnumerable()
:
var model = _service.GetQuery
.Where(data => data.SomeFlag == true)
.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows)
.AsEnumerable()
.Select(data => new { Foo = CalculateFoo(data.Bar); });
答案 1 :(得分:1)
如果您进行分页,则需要...页面和总计
所以
var query= _service.GetQuery
.Where(data => data.SomeFlag == true);
ViewBag.Total = query.Count();
var model = query.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows)
.AsEnumerable()
.Select(data => new { Foo = CalculateFoo(data.Bar); });
因为模型现在是IEnumerable而不是IQueryable,当我们说model.Skip()。Take()时,是否必须首先从数据库加载整个数据集才能跳过并取走? (这会破坏传呼的目的)
这是一个事实:在“分页”之前,你将始终只有你的“被linq2entites接受”的查询。
修改强>
我无法控制分页。我正在生成一个模型并将其传递给网格组件(在这种情况下为DevExpress,但可以是任何网格)。发出分页命令的是网格组件。任何涉及使用.Skip()的解决方案。在此之前无法使用AsEnumerable()之前的Take()。
嗯,“通常”网格系统允许(telerik)(或只有(MvcContrib)自定义分页(这意味着你必须提供“选定页面”结果+总数,如我的答案)。
我在“DevExpress自定义分页”上进行了搜索(你可以更进一步),结果很少。不知道他们是否对你有意思。
回答的例子