我有以下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,因为我只想要第一个结果中的包。
答案 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
)
)
)
注意根本没有订单,因为它最终无所谓。