使用 AsEnumerable() 对分页有什么影响?
本文关键字:什么 影响 分页 AsEnumerable 使用 | 更新日期: 2023-09-27 18:33:55
我知道,如果您在 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);
因为当我们说模型时,模型现在是 IEnumerable 而不是 IQueryable。跳过((。Take((,它是否必须先从数据库中加载整个数据集,然后才能跳过和获取?(这将破坏分页的目的(
编辑:这个问题是笼统地写的 - 这些是具体的细节:
我无法控制分页。我正在生成一个模型并将其传递给网格组件(在本例中为 DevExpress,但可以是任何网格(。 它是发出分页命令的网格组件。 任何涉及使用 的解决方案。跳过((。在 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);
});
所以现在我有一个岩石与硬地方的问题:
- 如果我将该模型传递给网格,它将在显示当前页面时引发异常,因为 linq to sql 无法执行 CalculateFoo((
- 如果我添加AsEnumerable((,那么网格可以显示当前页面,但它必须加载整个数据集才能这样做(加载数千行只是为了显示其中的200行(
- 如果我将 Foo 列排除在模型之外,那么我们再次延迟执行,但网格缺少一列
如果你进行分页,你需要...一页和总计
所以
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。跳过((。Take((,它是否必须先从数据库中加载整个数据集,然后才能跳过和获取?(这将破坏分页的目的(
这是一个事实:在"分页"之前,您将始终只有"被linq2entites接受"查询。
编辑
我无法控制分页。我正在生成一个模型并将其传递给网格组件(在本例中为 DevExpress,但可以是任何网格(。它是发出分页命令的网格组件。任何涉及使用 的解决方案。跳过((。在 AsEnumerable(( 之前 Take(( 在这里是不可能的。
好吧,">通常"网格系统允许(telerik((或只有(MvcContrib(自定义分页(这意味着您必须提供"所选页面"结果+总数,如我的回答所示(。
我在"DevExpress 自定义分页"上进行了搜索(您可以进一步搜索(,结果很少。不知道它们对你是否感兴趣。
答案示例
http://www.devexpress.com/Support/Center/p/Q264453.aspx
http://community.devexpress.com/forums/p/98848/338135.aspx
只需在AsEnumerable()
之前调用Skip/Take
:
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); });