0

我使用 LLBLgen 作为 ORM 并希望实现以下目标:

表 1
会话 ID

表 2
SessionId
时间戳

SELECT TOP 100 * FROM Table1
INNER JOIN Table2 ON Table1.SessionId = Table2.SessionId
ORDER BY Table2.Timestamp DESC

此代码在 SQL Server 2008 R2 上直接执行时运行良好 - 如果可用,则从 Table1 中准确返回 100 行,但不知何故,我无法使用 LLBLGen 获得相同的结果。目前我仍在使用 2.6,但如果需要,可以选择更新。

是否有可能在 LLBLGen 中实现这种行为?

如果我在 LLBLGen 中使用正常机制,这就是结果

SELECT * FROM Table1
INNER JOIN Table2 ON Table1.SessionId = Table2.SessionId
ORDER BY Table2.Timestamp DESC

顺便说一句:我读到 LLBLGen 从阅读器那里获取 TOP 100 结果,然后终止连接。尽管如此,与直接执行 SQL 相比,使用 LLBLGen 的查询需要更长的时间(令我惊讶的是,这对于后面的查询也很重要!)

4

1 回答 1

1

它不会添加 TOP 因为这可能会在您有连接时返回重复的行,并且您的查询中存在一种情况(您没有发布真正的查询),您的投影中有明显的违规类型字段。

通常,在获取实体时,llblgen pro 会在您的情况下添加 TOP 和 DISTINCT。如果它不能添加 distinct,因为您的查询返回类型为 image、ntext、text 的字段,或者您对不在投影中的字段进行排序(因此无法应用 distinct,否则 sqlserver 将抛出错误),它也不会添加 TOP,因为这可能意味着您在受 TOP 限制的集合中获得潜在的重复行,这些行被过滤掉,因为实体始终是唯一的。

示例:根据 Order 上的过滤器获取客户(因此使用连接),将在 Northwind 上创建客户 INNER JOIN 订单,但由于这是 1:n 关系,因此会创建重复项。如果客户包含文本、图像或 ntext 字段,则无法应用 distinct,因此如果我们随后指定 TOP,您将获得重复的行。由于 llblgen pro 永远不会将重复的行具体化为实体,因此您得到的实体将少于您要求的值。

因此,在这种特殊情况下,它会切换客户端限制:一旦它读取了您要求的实体数(而不是行!),它就会终止连接。因此,如果您要求 10 个实体并且在前 10010 行中有 10000 个重复行,那么您将至少获取 10000 行。

所以我的猜测是 table2 上的排序问题,因为这会阻止 DISTINCT 被发出。这是 sqlserver 上的非法查询:

SELECT DISTINCT C.CompanyName FROM Customers C INNER JOIN Orders O on c.CustomerId = o.CustomerId ORDER BY o.OrderDate DESC;

原因是 ORDER BY 为所有字段附加了一个隐藏列,以便对不在投影中的字段进行排序,这破坏了独特性。这在 RDBMS-s 中很常见。

所以 TL;DR: 这是一个功能:)

于 2012-05-16T13:16:09.863 回答