Linq заказ по ничего не заказывает - PullRequest
3 голосов
/ 04 апреля 2011
// Query all records
var q =
dc.tblHelpCentreQuestions.Where(question => question.userID == UserID).Where(question => question.awaitingUserResponse == true || question.awaitingSupportResponse == true).
OrderBy(s => s.awaitingUserResponse).ThenBy(s => s.dateSubmitted).
GroupJoin(
    dc.tblHelpCentreReplies,
    question => question.ID,
    replies => replies.ticketID,
    (question, replies) => new { Question = question, RepliesCount = replies.Count() }
);

Независимо от того, где я разместил заказ по запросу, похоже, он просто упорядочивает их случайным образом.

Редактировать: те же результаты, что и в конце заказа:

// Query all records
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);

Редактировать: Сгенерированный SQL

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

Я прогнал код через базу данных, и он правильно возвращает результаты, так что это должно быть что-то еще, что странно, потому что код такой простой, хотя не говоря уже, спасибо всемс вашей помощью я узнал много нового с этой проблемой!

Ответы [ 6 ]

4 голосов
/ 04 апреля 2011

Это LINQ to 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);

РЕДАКТИРОВАТЬ: Хорошо, если это не работает, то, возможно, это ограничение группировки 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() })
          // Force the rest of the query to execute in .NET code (Enumerable.XXX)
          .AsEnumerable()
          .OrderBy(s => s.Question.awaitingUserResponse)
          .ThenBy(s => s.Question.dateSubmitted);
3 голосов
/ 04 апреля 2011

Если вы хотите заказать сгруппированные вопросы, вам нужно сделать это после создания 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() }
    ).
    AsEnumerable().
    OrderBy(s => s.Question.awaitingUserResponse).
    ThenBy(s => s.Question.dateSubmitted);

GroupJoin эффективно удалит ваш заказ, так как он принимает вашу заказанную коллекцию и группирует ее по вопросу. GroupJoin не сохраняет начальный порядок ключей.

Редактировать: Вы можете устранить эту проблему, заставив упорядочение в LINQ to Objects, преобразовав в перечислимое после GroupJoin.

3 голосов
/ 04 апреля 2011

GroupJoin, скорее всего, переопределяет заказ.Скорее всего, это реализовано как подзапрос.Если вы запустите LINQ to SQL Profiler или SQL profiler, чтобы увидеть базовый запрос, он сможет пролить свет на это.Вы пытались сделать OrderBy как последнюю операцию в цепочке методов?

3 голосов
/ 04 апреля 2011

Вы пытались переместить OrderBy до самой последней операции, непосредственно перед;?Как и в случае с SQL, я не ожидал бы получить упорядоченный набор, если бы выполнил ЛЮБЫЕ операции с ним после упорядочения ... Мне было бы любопытно посмотреть, что представляет собой фактически сгенерированный SQL при представлении в таком порядке.

Отредактируйте для изучения кода с помощью ToList () для принудительного выполнения, а затем выполните заказ клиента:

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);
2 голосов
/ 04 апреля 2011

попробуйте добавить ToArray () после вашего запроса LINQ.Я знаю, что LINQ следует ленивому правилу оценки, и ToArray () заставляет оценку стремиться.

2 голосов
/ 04 апреля 2011

Трудно протестировать ваш код, потому что у меня нет всех ваших объявлений, но я подозреваю, что причина, по которой вы получаете на первый взгляд случайное поведение, заключается в том, что 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() }
    )
    .OrderBy(s => s.Question.awaitingUserResponse)
    .ThenBy(s => s.Question.dateSubmitted);
...