2015-05-10 2 views
3

У меня есть следующий код C#, создающий запрос на sqlserver.Заказ отсутствующий в запросе рамки сущности

return c.Bags 
     .Where(b => b.RollformerId == RollformerId 
      && (!b.Order.OnHold.HasValue || b.Order.OnHold.Value == false) 
      && (!b.Order.Archive.HasValue || b.Order.Archive.Value == false) 
      && (!b.Order.Inactive.HasValue || b.Order.Inactive.Value == false) 
      && (b.BagStatus.BagStatusId == notStarted 
          || b.BagStatus.BagStatusId == inProgress)) 
     .OrderBy(b => b.Priority) 
     .ThenBy(b => b.ScheduleDate) 
     .SelectMany(b => b.Packs 
        .OrderBy(p => p.PackSequence)) 
     .FirstOrDefault(); 

Он генерирует следующий SQL код:

SELECT 
[Limit1].[BatchID] AS [BatchID], 
[Limit1].[RollformerID] AS [RollformerID], 
[Limit1].[Description] AS [Description], 
[Limit1].[OrderID] AS [OrderID], 
[Limit1].[BagId] AS [BagId], 
[Limit1].[PackSequence] AS [PackSequence], 
[Limit1].[PackStatusId] AS [PackStatusId], 
[Limit1].[Priority] AS [Priority], 
[Limit1].[ProductID] AS [ProductID], 
[Limit1].[DeliveryID] AS [DeliveryID] 
FROM (SELECT TOP (1) 
    [Extent4].[BatchID] AS [BatchID], 
    [Extent4].[DeliveryID] AS [DeliveryID], 
    [Extent4].[Priority] AS [Priority], 
    [Extent4].[ProductID] AS [ProductID], 
    [Extent4].[RollformerID] AS [RollformerID], 
    [Extent4].[Description] AS [Description], 
    [Extent4].[OrderID] AS [OrderID], 
    [Extent4].[BagId] AS [BagId], 
    [Extent4].[PackSequence] AS [PackSequence], 
    [Extent4].[PackStatusId] AS [PackStatusId] 
    FROM [dbo].[Bag] AS [Extent1] 
    INNER JOIN [dbo].[Orders] AS [Extent2] ON [Extent1].[OrderId] = [Extent2].[OrderID] 
    LEFT OUTER JOIN [dbo].[Orders] AS [Extent3] ON [Extent1].[OrderId] = [Extent3].[OrderID] 
    INNER JOIN [dbo].[Batches] AS [Extent4] ON [Extent1].[BagId] = [Extent4].[BagId] 
    WHERE ([Extent2].[OnHold] IS NULL OR [Extent3].[OnHold] = 0) 
    AND ([Extent3].[Archive] = 0 OR [Extent3].[Archive] IS NULL) 
    AND ([Extent3].[Inactive] = 0 OR [Extent3].[Inactive] IS NULL) 
    AND ([Extent1].[RollformerId] = @p__linq__0) 
    AND ([Extent1].[BagStatusId] IN (@p__linq__1,@p__linq__2)) 
) AS [Limit1] 

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

Не могли бы кто-нибудь объяснить, что не так с моим заявлением, чтобы игнорировать заказ.

Решение, представленное в Ordering not working in Entity Framework query не устраивает эту ситуацию (по крайней мере, к моему удовольствию)

UPDATE:

Первый набор OrderBy находится на главной сущности, где я хочу, чтобы выбрать первую в порядке, а последующее selectmany находится в подробных записях или я хочу получить первое.

Подумайте об этом, selectmany не требуется в этом случае, так как мне нужны пакеты только от первого результата.

+0

Я не хочу публиковать это как ответ, потому что я не знаю, так ли это, но это может помочь вам подумать о проблеме. Я думаю, что это связано с тем, что ни один из ваших заказов по частям не влияет на результат. Это похоже на то, что ORDER BY в представлении - бессмысленно, потому что вы хотите ЗАКАЗАТЬ конечным результатом. Поэтому я думаю, что вам нужно иметь свой .OrderBy после того, как вы выбрали SelectMany и FirstOrDefault, а не захоронены внутри. – LoztInSpace

+0

@LoztInSpace Понятно, что я немного понимаю, но 'OrderBy()' после 'FirstOrDefault()' не имеет особого смысла - это странно. – jdphenix

+0

Извините - не то, что я говорю. Do .Where.SelectMany.OrderBy.FirstOrDefault. – LoztInSpace

ответ

1

На основе вашего обновления, я думаю, что вы стремитесь к чему-то вроде этого:

return c.Bags 
     .Where(b => b.RollformerId == RollformerId 
      && (!b.Order.OnHold.HasValue || b.Order.OnHold.Value == false) 
      && (!b.Order.Archive.HasValue || b.Order.Archive.Value == false) 
      && (!b.Order.Inactive.HasValue || b.Order.Inactive.Value == false) 
      && (b.BagStatus.BagStatusId == notStarted 
          || b.BagStatus.BagStatusId == inProgress)) 
     .OrderBy(b => b.Priority) 
     .ThenBy(b => b.ScheduleDate) 
     .FirstOrDefault().Packs 
     .Select(b => b.Packs) 
     .OrderBy(p => p.PackSequence); 

Это выбрать и заказать Bag объекты в соответствии с вашим исходным запросом, возьмите верхнюю один, а затем выбрать и заказать bag.Packs коллекция на выбранных Bag.


Оригинальный ответ ниже.

@ LoztInSpace имеет правильную идею здесь.

В конечном счете, когда вы используете SelectMany() и придавить результаты, как вы делаете, вы хотите OrderBy(), ThenBy() ect after the SelectOrMany() `вызова.

Рассмотрим вывод этого запроса:

var qry = ctx.Users 
    .Where(u => u.EmailAddress != String.Empty) 
    .SelectMany(u => u.Surveys) 
    .OrderBy(s => s.Time) 
    .ThenBy(s => s.Respondent_Uid); 

SELECT [Project1].[Id] AS [Id] 
    ,[Project1].[Time] AS [Time] 
    ,[Project1].[Type] AS [Type] 
    ,[Project1].[Respondent_Uid] AS [Respondent_Uid] 
    ,[Project1].[SubjectOfSurvey_Uid] AS [SubjectOfSurvey_Uid] 
FROM (
    SELECT [Extent2].[Id] AS [Id] 
     ,[Extent2].[Time] AS [Time] 
     ,[Extent2].[Type] AS [Type] 
     ,[Extent2].[Respondent_Uid] AS [Respondent_Uid] 
     ,[Extent2].[SubjectOfSurvey_Uid] AS [SubjectOfSurvey_Uid] 
    FROM [dbo].[Users] AS [Extent1] 
    INNER JOIN [dbo].[Surveys] AS [Extent2] ON [Extent1].[Uid] = [Extent2].[Respondent_Uid] 
    WHERE NOT (
      ([Extent1].[EmailAddress] = @p__linq__0) 
      AND (
       0 = (
        CASE 
         WHEN (@p__linq__0 IS NULL) 
          THEN cast(1 AS BIT) 
         ELSE cast(0 AS BIT) 
         END 
        ) 
       ) 
      ) 
    ) AS [Project1] 
ORDER BY [Project1].[Time] ASC 
    ,[Project1].[Respondent_Uid] ASC 

Порядок по где мы хотим там. Контраст с этим запросом:

var qry = ctx.Users 
    .Where(u => u.EmailAddress != String.Empty) 
    .OrderBy(u => u.FirstName) 
    .SelectMany(u => u.Surveys.OrderBy(s => s.Time)); 

SELECT [Extent2].[Id] AS [Id] 
    ,[Extent2].[Time] AS [Time] 
    ,[Extent2].[Type] AS [Type] 
    ,[Extent2].[Respondent_Uid] AS [Respondent_Uid] 
    ,[Extent2].[SubjectOfSurvey_Uid] AS [SubjectOfSurvey_Uid] 
FROM [dbo].[Users] AS [Extent1] 
INNER JOIN [dbo].[Surveys] AS [Extent2] ON [Extent1].[Uid] = [Extent2].[Respondent_Uid] 
WHERE NOT (
     ([Extent1].[EmailAddress] = @p__linq__0) 
     AND (
      0 = (
       CASE 
        WHEN (@p__linq__0 IS NULL) 
         THEN cast(1 AS BIT) 
        ELSE cast(0 AS BIT) 
        END 
       ) 
      ) 
     ) 

Обратите внимание, что никакого порядка нет, потому что это в конечном счете не имеет значения.

+0

Красивый пример. Позор я был слишком ленив, чтобы написать один вверх :) Это довольно распространенная проблема с SQL: в представлении или подзапросе есть ORDER BY, но не в действительности. SELECT – LoztInSpace

+0

Имея orderby после того, как selectmany изменит результат запроса. selectmany находится в подробных записях, тогда как начальное упорядочение находится на основных записях. – sweetfa

+0

@sweetfa Я обновляюсь на основе того, что, как я считаю, является вашим намерением. – jdphenix

Смежные вопросы