【问题标题】:IQueryable against SQL 2000 Paging with JoinsIQueryable 针对带有连接的 SQL 2000 分页
【发布时间】:2009-04-08 16:32:42
【问题描述】:

我有一个包含大约 10 个连接的查询。使用列表视图和 Linq 数据源,它对 SQL2008 进行了很好的分页,但在对 SQL2000 运行时无法产生正确的结果。没有抛出异常,但结果显然是乱序的,有时会返回相同的页面。通读 LINQ Docs,SQL2000 不支持对带有连接的查询进行分页。说得够多了,虽然我本以为会有例外。

我现在无法将数据移出 SQL2000。解决方案是执行完整查询,然后执行基于内存的分页。

protected void LinqDataSourceMain_Selecting(object sender,
    LinqDataSourceSelectEventArgs e)
{
    // var query = myquery with join...
    e.Result = query.ToList();
}

现在的问题是:调用 ToList() 还是 ToArray() 效率更高?

AsEnumerable() 不能解决问题。查看使用反射器的扩展方法,它只是返回“源”,所以这对我来说很有意义。

e.Result = query.AsEnumerable();
public static IEnumerable<TSource> AsEnumerable<TSource>(
    this IEnumerable<TSource> source)
{
    return source;
}

但是,下面的方法会比 ToList() 或 ToArray() 更有效吗?它确实有效,并且确实推迟了执行。

e.Result = query.ToEnumerable();

public static IEnumerable<TSource> ToEnumerable<TSource>(
    this IEnumerable<TSource> source)
{
    foreach (var item in source)
        yield return item;
}

【问题讨论】:

    标签: asp.net linq


    【解决方案1】:

    ToList() 将比ToArray() 更高效,因为它不需要将最终从超大缓冲区复制到固定大小的数组。

    如果您要进行内存分页,则不想要延迟执行 (IMO),因为您需要获取项目数和随机访问。您不希望每次都重新执行查询。

    【讨论】:

    • 谢谢。我每次都需要重新查询,因为这是一个 Web 应用程序,我真的不想将结果存储在临时位置,例如 Session。还在推迟执行的栅栏上吗?我的头发分裂?最后,我应该可以离开 sql 2k 但不是现在。
    • 出于兴趣,您将如何计算要显示的页数?结果乱序的事实表明,无论您做什么都会遇到问题 - 除非您可以使排序顺序保持一致,否则您不可能明智地分页,除非我遗漏了什么。
    • 当我返回一个列表时,分页和排序工作正常。当我返回一个 IQueryable 时它失败了。使用 IQ,第一页显示正确,但随后事情从那里开始分崩离析。查看 SQL 分析器,SQL 真的很讨厌。子查询上的子查询上的子查询上的连接等。
    • 针对 SQL 2008 生成的 SQL 非常干净。猜测通过在 LDS_Selecting 事件中推迟执行,它不会被推迟很长时间。即使使用分页和延迟执行,完整的查询仍然会针对 SQL 运行。只是想知道将活动推迟一段时间是否更好?
    • 乔恩,答案的不同方法。 query.ToList(); 的 sql 跟踪是相同的。或 query.ToEnumerable(); ToEnumerable() 是否更有效,因为它不分配列表,就像列表比 ToArray 更有效?忽略延迟执行部分。
    猜你喜欢
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 2017-03-20
    相关资源
    最近更新 更多