Linq SQL出现一对多关系和复杂表达式排序的错误

4
我将使用Entity Framework v6.1.3进行翻译。下面是一个Linq语句的例子:
return _context.Postings
            .Where(p => p.dateToBeRemoved >= asOf)
            .Include(p => p.Region)
            .Include(p => p.Positions)
            .OrderByDescending(p => p.oldVacancyId ?? int.MaxValue)
            .ThenByDescending(p => p.postingNumber);

生成以下 SQL 代码:

SELECT 
[Project1].[postingId] AS [postingId], 
[Project1].[regionId1] AS [regionId1], 
<--- lines removed for brevity -->
[Project1].[C2] AS [C1]
FROM ( SELECT 
    CASE WHEN ([Extent1].[oldVacancyId] IS NULL) THEN 2147483647 ELSE [Extent1].[oldVacancyId] END AS [C1], 
    [Extent1].[postingId] AS [postingId], 
    [Extent2].[regionId] AS [regionId1], 
    <--- lines removed for brevity -->
    CASE WHEN ([Extent3].[postingPositionId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
    FROM   [dbo].[Postings] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Regions] AS [Extent2] ON [Extent1].[regionId] = [Extent2].[regionId]
    LEFT OUTER JOIN [dbo].[PostingPositions] AS [Extent3] ON [Extent1].[postingId] = [Extent3].[postingId]
    WHERE [Extent1].[dateToBeRemoved] >= '2016/6/3'
)  AS [Project1]
ORDER BY [Project1].[C1] DESC, [Project1].[postingNumber] DESC, [Project1].[postingId] ASC, [Project1].[regionId1] ASC, [Project1].[C2] ASC

运行时出现以下错误:

在order by列表中指定了超过一次的列。 order by列表中的列必须唯一。

问题出在顶层select中给Project1.C2赋的别名上。它被命名为C1,而C1是Project1子查询中另一个列的别名。删除第一个或第五个order by字段之一可以使查询运行,但排序不正确。将别名重命名为其他名称可以使查询运行并且排序正确。这是Linq中的一个bug吗?有什么解决方法吗?

编辑

这是我问题的最小演示。给定这三个表:

Dogs
-------------------------
dogId int NOT NULL
dogName varchar NOT NULL
groomerId int NULL


Groomers
----------------------------
groomerId int NOT NULL
groomerName varchar NOT NULL


Fleas
----------------------------
fleaId int NOT NULL
fleaName varchar NOT NULL
hostDogId int NOT NULL

一只狗可能有也可能没有美容师,可能有 0 到多只跳蚤。
然后像下面这样的 Linq 查询:
_context.Dogs
   .Include(d => d.Fleas)
   .OrderBy(d => d.groomerId.HasValue);

生成的 SQL 将包含一个内部查询,其中有 2 个复杂表达式-一个用于指示狗是否有美容师,另一个用于指示其是否有跳蚤。这两个表达式都被赋予一个别名(分别为 C1 和 C2)。该内部查询被外部查询包装,外部查询引用了 C2 并将其分配给别名 C1。然后将 C1 和 C2 放入 order by 子句中,但 SQL 对哪个 C1 感到困惑,从而产生上述错误。

我认为重复别名不是问题。在外部查询和子查询之间有重复应该是没问题的。你能展示一下[Project1].[regionId1]来自哪里吗? - Steven Kushubar
删除第一或第五个排序字段中的任何一个都可以使查询运行,但排序不正确。将别名重命名为其他名称可以使查询运行并且排序正确。我在问题中添加了regionId1到查询中。 - Robin
很奇怪,我无法通过一个同样结构的查询在EF 6.1.3和Sql Server(2014)上重现这个问题。 - Gert Arnold
无法重现。上述查询运行良好。需要提供最小可复现示例(MCVE)。 - Ivan Stoev
我在问题中添加了一个最小示例。我使用的是SQL Server 2008 R2 SP3 - 也许这就是我的问题所在。 - Robin
显示剩余3条评论
1个回答

0

我无法在单个Linq语句中解决这个问题。目前我的解决方法是在不包含排序子句的情况下运行查询并输出一个列表。然后在第二个语句中,将排序子句应用于该列表。

var dogs = _context.Dogs.Include(d => d.Fleas).ToList();
dogs = dogs.OrderBy(d => d.groomerId.HasValue).ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接