2

现在,我收到以下错误:

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.

这是我的查询:

var issues = from issue in this.IssueDatas
             join original in this.NoteDatas on issue.NoteDatas
                                                     .OrderBy(n => n.CreatedDate)
                                                     .Select(n => n.NoteId)
                                                     .First() equals original.NoteId
             join current in this.NoteDatas on issue.NoteDatas
                                                    .OrderByDescending(n => n.CreatedDate)
                                                    .Select(n => n.NoteId)
                                                    .First() equals current.NoteId
             select { whatever, i, want, to, select }

获取这些 TOP 1 id 的 SQL 部分如下所示:

SELECT whatever, i, want, to
FROM [dbo].[issue_Details] AS [t0]
INNER JOIN [dbo].[issue_notes] AS [t1] ON ((
    SELECT TOP (1) [t3].[id]
    FROM (
        SELECT [t2].[id], [t2].[issue_id]
        FROM [dbo].[issue_notes] AS [t2]
        ORDER BY [t2].[CreatedDate]
        ) AS [t3]
    WHERE [t3].[issue_id] = [t0].[IssueDetailsId]
    )) = [t1].[id]
INNER JOIN [dbo].[issue_notes] AS [t4] ON ((
    SELECT TOP (1) [t6].[id]
    FROM (
        SELECT [t5].[id], [t5].[issue_id]
        FROM [dbo].[issue_notes] AS [t5]
        ORDER BY [t5].[CreatedDate] DESC
        ) AS [t6]
    WHERE [t6].[issue_id] = [t0].[IssueDetailsId]
    )) = [t4].[id]

...但它应该看起来更像这样:

FROM [dbo].[issue_Details] AS [t0]
INNER JOIN [dbo].[issue_notes] AS [t1] ON (
    SELECT TOP (1) [t2].[id]
    FROM [dbo].[issue_notes] AS [t2]
    ORDER BY [t2].[CreatedDate]
    WHERE [t2].[issue_id] = [t0].[IssueDetailsId]
    ) = [t1].[id]
INNER JOIN [dbo].[issue_notes] AS [t4] ON (
    SELECT TOP (1) [t5].[id]
    FROM [dbo].[issue_notes] AS [t5]
    ORDER BY [t5].[CreatedDate] DESC
    WHERE [t5].[issue_id] = [t0].[IssueDetailsId]
    ) = [t4].[id]

我尝试使用this.NoteDatas而不是issue.NoteDatas手动应用 id 过滤器,我尝试选择第一个音符,然后获取 id(反转我在上面输入的内容),我尝试使用Take(int)而不是First()......我只是不不知道该怎么办。LINQ 的读取比它生成的 SQL 更直接。

4

2 回答 2

0

这就是我最终更改 LINQ 以使其工作的方式:

var issues = from issue in this.IssueDatas
             join original in this.NoteDatas on issue.NoteDatas
                                                     .Min(n => n.CreatedDate) equals original.CreatedDate
             join current in this.NoteDatas on issue.NoteDatas
                                                    .Max(n => n.CreatedDate) equals current.CreatedDate
             select { whatever, i, want, to, select }
于 2013-11-14T23:10:44.190 回答
0

这样:

 join original in this.NoteDatas on issue.NoteDatas
                                         .OrderBy(n => n.CreatedDate)
                                         .Select(n => n.NoteId)
                                         .First() equals original.NoteId

您说的是“按 CreatedDate 排序,从结果中取出第一行并检查它是否等于 NoteId”。这被正确地呈现为:

INNER JOIN [dbo].[issue_notes] AS [t1] ON ((
    SELECT TOP (1) [t3].[id]
    FROM (
        SELECT [t2].[id], [t2].[issue_id]
        FROM [dbo].[issue_notes] AS [t2]
        ORDER BY [t2].[CreatedDate]
        ) AS [t3]
    WHERE [t3].[issue_id] = [t0].[IssueDetailsId]
    )) = [t1].[id]

所以t2.id对于任何外部来说总是相同的,[t1].[id]但仅取决于[t0].[IssueDetailsId]

样本:

    var issues = new Tuple<int, string>[]
        {
            new Tuple<int, string>(1, "aaa"),
            new Tuple<int, string>(2, "bbb")
        };
    var notes = new Tuple<int, DateTime, string>[]
        {
            new Tuple<int, DateTime, string>(1, DateTime.Parse("01/01/2001"), "earliest for 1"),
            new Tuple<int, DateTime, string>(1, DateTime.Parse("02/01/2001"), "middle for 1"),
            new Tuple<int, DateTime, string>(1, DateTime.Parse("03/01/2001"), "latest for 1"),
            new Tuple<int, DateTime, string>(2, DateTime.Parse("10/01/2001"), "earliest for 2"),
            new Tuple<int, DateTime, string>(2, DateTime.Parse("11/01/2001"), "middle for 2"),
            new Tuple<int, DateTime, string>(2, DateTime.Parse("12/01/2001"), "once more middle for 2"),
            new Tuple<int, DateTime, string>(2, DateTime.Parse("13/01/2001"), "latest for 2")
        };

        var result =
            ctx.Set<Parent>().Select(i => new
                {
                    i.Id,
                    e = ctx.Set<Child>().Where(c => c.ParentId == i.Id).OrderBy(c => c.Name).FirstOrDefault(),
                    l = ctx.Set<Child>().Where(c => c.ParentId == i.Id).OrderByDescending(c => c.Name).FirstOrDefault()
                });
于 2013-11-14T21:53:47.067 回答