在实体框架查询中排序缺失

时间:2015-05-10 06:34:51

标签: c# entity-framework entity-framework-6

我有以下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]

将输出与原始输出进行比较,似乎排序语句在生成的SQL中已被完全忽略

有人可以确定我的陈述有什么问题,以便忽略排序。

Ordering not working in Entity Framework query中提供的解决方案不适合这种情况(至少令我满意)

更新:

第一组orderby在主实体上,我希望在顺序中选择第一组,后续的selectmany在详细记录上,或者我希望得到第一组。

考虑到这一点,在这种情况下不需要selectmany,因为我只想要第一个结果中的包。

1 个答案:

答案 0 :(得分: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()`call。

考虑此查询的输出:

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
                )
            )
        )

注意根本没有订单,因为它最终无所谓。

相关问题