gpt4 book ai didi

mysql - 我们可以使用 Skip()、Take() 和 OrderBy() 来控制 LINQ 表达式顺序吗

转载 作者:IT王子 更新时间:2023-10-28 23:50:02 27 4
gpt4 key购买 nike

我正在使用 LINQ to Entities 来显示分页结果。但我对 Skip()Take()OrderBy() 调用的组合有问题。

一切正常,除了 OrderBy() 赋值太晚。它在结果集被 Skip()Take() 削减后执行。

所以每一页结果都有顺序排列的项目。但排序是在一页数据上完成的,而不是对整个集合进行排序,然后使用 Skip()Take() 限制这些记录。

如何设置这些语句的优先级?

我的例子(简化)

var query = ctx.EntitySet.Where(/* filter */).OrderByDescending(e => e.ChangedDate);
int total = query.Count();
var result = query.Skip(n).Take(x).ToList();

一种可能(但不好)的解决方案

一种可能的解决方案是应用聚簇索引按列排序,但该列经常更改,这会降低插入和更新时的数据库性能。我真的不想那样做。

编辑

我在查询中运行了 ToTraceString(),我们可以在其中实际看到 order by 何时应用于结果集。不幸的是最后。 :(

SELECT 
-- columns
FROM (SELECT
-- columns
FROM (SELECT -- columns
FROM ( SELECT
-- columns
FROM table1 AS Extent1
WHERE EXISTS (SELECT
-- single constant column
FROM table2 AS Extent2
WHERE (Extent1.ID = Extent2.ID) AND (Extent2.userId = :p__linq__4)
)
) AS Project2
limit 0,10 ) AS Limit1
LEFT OUTER JOIN (SELECT
-- columns
FROM table2 AS Extent3 ) AS Project3 ON Limit1.ID = Project3.ID
UNION ALL
SELECT
-- columns
FROM (SELECT -- columns
FROM ( SELECT
-- columns
FROM table1 AS Extent4
WHERE EXISTS (SELECT
-- single constant column
FROM table2 AS Extent5
WHERE (Extent4.ID = Extent5.ID) AND (Extent5.userId = :p__linq__4)
)
) AS Project6
limit 0,10 ) AS Limit2
INNER JOIN table3 AS Extent6 ON Limit2.ID = Extent6.ID) AS UnionAll1
ORDER BY UnionAll1.ChangedDate DESC, UnionAll1.ID ASC, UnionAll1.C1 ASC

最佳答案

我的解决方案

我已经设法解决了这个问题。别误会我的意思。到目前为止,我还没有解决优先级问题,但我已经缓解了它。

我做了什么?

这是我从 Devart 得到答案之前一直使用的代码。如果他们无法解决这个问题,我最终将不得不使用此代码。

// get ordered list of IDs
List<int> ids = ctx.MyEntitySet
.Include(/* Related entity set that is needed in where clause */)
.Where(/* filter */)
.OrderByDescending(e => e.ChangedDate)
.Select(e => e.Id)
.ToList();

// get total count
int total = ids.Count;

if (total > 0)
{
// get a single page of results
List<MyEntity> result = ctx.MyEntitySet
.Include(/* related entity set (as described above) */)
.Include(/* additional entity set that's neede in end results */)
.Where(string.Format("it.Id in {{{0}}}", string.Join(",", ids.ConvertAll(id => id.ToString()).Skip(pageSize * currentPageIndex).Take(pageSize).ToArray())))
.OrderByDescending(e => e.ChangedOn)
.ToList();
}

首先,我得到了我的实体的有序 ID。即使使用更大的数据集,仅获取 ID 的性能也很好。 MySql 查询非常简单并且性能非常好。在第二部分中,我对这些 ID 进行了分区,并使用它们来获取实际的实体实例。

考虑到这一点,这应该比我开始时的方式表现得更好(如我的问题中所述),因为由于简化了查询,获得总计数要快得多。第二部分实际上非常相似,只是我的实体是通过它们的 ID 返回的,而不是使用 SkipTake...

进行分区

希望有人会发现此解决方案有帮助。

关于mysql - 我们可以使用 Skip()、Take() 和 OrderBy() 来控制 LINQ 表达式顺序吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2493900/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com