C# 由isn订购的Linq';我什么都不点
无论我在哪里查询订单,它似乎只是随机排序 编辑:与结尾处的顺序相同的结果: 编辑:生成的SQLC# 由isn订购的Linq';我什么都不点,c#,linq,lambda,sql-order-by,C#,Linq,Lambda,Sql Order By,无论我在哪里查询订单,它似乎只是随机排序 编辑:与结尾处的顺序相同的结果: 编辑:生成的SQL 我已经在数据库中运行了代码,它正确地返回了结果,所以它一定是另一个奇怪的东西,因为代码很简单,不过没关系,谢谢大家的帮助,我从这个问题中学到了很多新东西 您是否尝试将OrderBy移动到最后一个操作,就在;?像SQL一样,如果我在排序之后对它执行任何操作,我也不会期望收到一个排序集。。。我很想知道,当以这种顺序呈现时,实际生成的SQL是什么 使用ToList()编辑代码探索以强制执行,然后执行排序客户
我已经在数据库中运行了代码,它正确地返回了结果,所以它一定是另一个奇怪的东西,因为代码很简单,不过没关系,谢谢大家的帮助,我从这个问题中学到了很多新东西 您是否尝试将OrderBy移动到最后一个操作,就在;?像SQL一样,如果我在排序之后对它执行任何操作,我也不会期望收到一个排序集。。。我很想知道,当以这种顺序呈现时,实际生成的SQL是什么 使用ToList()编辑代码探索以强制执行,然后执行排序客户端:
exec sp_executesql N'SELECT [t2].[ID], [t2].[catID], [t2].[subject], [t2].[question], [t2].[userID], [t2].[dateSubmitted], [t2].[isUrgent], [t2].[emailMe], [t2].[awaitingSupportResponse], [t2].[awaitingUserResponse], [t2].[lastReply], [t2].[stopWatchTotalMins], [t2].[isStopWatchOn], [t2].[stopWatchStart], [t2].[priorityLevel], [t2].[value] AS [RepliesCount]
FROM (
SELECT [t0].[ID], [t0].[catID], [t0].[subject], [t0].[question], [t0].[userID], [t0].[dateSubmitted], [t0].[isUrgent], [t0].[emailMe], [t0].[awaitingSupportResponse], [t0].[awaitingUserResponse], [t0].[lastReply], [t0].[stopWatchTotalMins], [t0].[isStopWatchOn], [t0].[stopWatchStart], [t0].[priorityLevel], (
SELECT COUNT(*)
FROM [dbo].[tblHelpCentreReplies] AS [t1]
WHERE ([t0].[ID]) = [t1].[ticketID]
) AS [value]
FROM [dbo].[tblHelpCentreQuestions] AS [t0]
) AS [t2]
WHERE (([t2].[awaitingUserResponse] = @p0) OR ([t2].[awaitingSupportResponse] = @p1)) AND ([t2].[userID] = @p2)
ORDER BY [t2].[awaitingUserResponse], [t2].[dateSubmitted]', N'@p0 int,@p1 int,@p2 int', @p0 = 1, @p1 = 1, @p2 = 81
GroupJoin最有可能覆盖订单。它可能实现为一个子查询。如果您运行LINQtoSQLProfiler或SQLProfiler来查看底层查询,它将能够阐明这一点。您是否尝试过将OrderBy作为方法链中的最后一个操作?如果您想对分组问题进行排序,您需要在创建GroupJoin后进行排序:
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse == true || question.awaitingSupportResponse == true)
.GroupJoin(
dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question, RepliesCount = replies.Count() }
)
.ToList()
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);
GroupJoin
将有效地删除您的订购,因为它会将您订购的集合按问题进行分组GroupJoin
不保留键的初始顺序
编辑:通过强制在LINQ to对象中进行排序,并在GroupJoin之后转换为可枚举项,可以消除此问题。这是LINQ to SQL吗?我想问题是你在分组之前就下单了。你可以试试这个:
var q =
dc.tblHelpCentreQuestions.Where(question => question.userID == UserID).Where(question => question.awaitingUserResponse == true || question.awaitingSupportResponse == true).
GroupJoin(
dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question, RepliesCount = replies.Count() }
).
AsEnumerable().
OrderBy(s => s.Question.awaitingUserResponse).
ThenBy(s => s.Question.dateSubmitted);
编辑:好的,如果这不起作用,那么可能是SQL分组的限制。。。尽管这看起来很奇怪
您始终可以强制在客户端执行订购,尽管:
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse
|| question.awaitingSupportResponse)
.GroupJoin(dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question,
RepliesCount = replies.Count() })
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);
测试您的代码很困难,因为我没有您所有的声明,但我怀疑您获得看似随机行为的原因是
GroupJoin
无法保证保持顺序完整
因此,您必须在分组后进行排序
例如:
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse
|| question.awaitingSupportResponse)
.GroupJoin(dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question,
RepliesCount = replies.Count() })
// Force the rest of the query to execute in .NET code (Enumerable.XXX)
.AsEnumerable()
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);
尝试在LINQ查询之后添加ToArray()。我确实知道LINQ遵循惰性求值规则,而ToArray()强制求值是急切的 你想点什么?你是在排序之后进行连接的,所以顺序基本上被破坏了。在
GroupJoin
之后呢?你看过这篇文章了吗?你对这两种情况下生成的SQL都有很多了解吗?你的问题没有足够的信息来回答。仅基于您发布的代码,结果应该是有序的。在迭代这些结果时,可能您做错了什么(因为您只向我们展示了查询,而没有展示如何使用它)。感谢您的回答,尽管结果相同:saccordo and,GroupJoin
保留ordering@BlueRaja:这是LINQ to对象,这完全是另一回事儿。@Tom:我有一个建议。但我还是很惊讶它不起作用。。。SQL是什么样子的?@BlueRaja:虽然它对顺序做出了保证,但没有记录这样的保证。谢谢回答,尽管结果相同:感谢回答,尽管结果相同:感谢回答,尽管结果相同:感谢回答,尽管结果相同:你要立即处理结果吗?数据集有多大?您可以调用.ToList()强制执行查询并获取内存集,然后按原样“事后”进行排序。感谢您的回答,但结果相同:如果您执行GroupJoin(…).AsEnumerable().OrderBy(…).ThenBy(…)
,则排序是在.NET中进行的,而不是在数据库中进行的?这将q
从IQueryable
更改为IEnumerable
,但对于其余的代码,这可能没问题。另外,有时.NET中的排序比SQL快。对@Jim和@Jon来说有点脱轨:我看到你们都使用了AsEnumerable(),我本能地选择了ToList()。走列表路线有什么负面影响我应该注意吗?@Jon:我没看到。伟大的思想都是一样的。@Pete:ToList()迫使LINQ创建一个列表,然后立即进行GC'd,而AsEnumerable()可能更有效,尽管我怀疑它是否有意义。
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse
|| question.awaitingSupportResponse)
.GroupJoin(dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question,
RepliesCount = replies.Count() })
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse
|| question.awaitingSupportResponse)
.GroupJoin(dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question,
RepliesCount = replies.Count() })
// Force the rest of the query to execute in .NET code (Enumerable.XXX)
.AsEnumerable()
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);
var q = dc.tblHelpCentreQuestions
.Where(question => question.userID == UserID)
.Where(question => question.awaitingUserResponse == true || question.awaitingSupportResponse == true)
.GroupJoin(
dc.tblHelpCentreReplies,
question => question.ID,
replies => replies.ticketID,
(question, replies) => new { Question = question, RepliesCount = replies.Count() }
)
.OrderBy(s => s.Question.awaitingUserResponse)
.ThenBy(s => s.Question.dateSubmitted);