Linq SQL错误与一对多关系和orderby复杂表达式

时间:2016-06-03 18:22:01

标签: sql sql-server linq entity-framework-6 alias

我正在使用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

运行时会抛出此错误:

  

已按列表顺序多次指定列。   按列表排列的列必须是唯一的。

问题在于顶级选择中给予Project1.C2的别名。它是别名为C1,它是Project1子查询中另一列的别名。 删除第一个或第五个ordery字段允许查询运行,但排序不正确。将别名重命名为其他内容允许运行查询并且排序正确。这是Linq的一个错误吗?有关如何解决此问题的任何建议吗?

修改

以下是我的问题的最小示范。鉴于这三个表:

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导致上述错误感到困惑。

1 个答案:

答案 0 :(得分:0)

我无法在单个linq语句中解决此问题。我现在的解决方法是在没有子句的情况下运行查询并输出List。然后在第二个语句中,将order by子句应用于该列表。

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