[英]How to join based on the top 1 id of another table using Linq to SQL?
Right now, I receive the following error: 现在,我收到以下错误:
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.
This is my query: 这是我的查询:
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 }
The SQL portion to grab those TOP 1 ids comes out like this: 抓住那些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]
...but it should look more like this: ...但是看起来应该更像这样:
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]
I've tried using this.NoteDatas
instead of issue.NoteDatas
and manually applying the id filter, I've tried selecting the first note and then taking the id (reversing what I've typed above), I've tried using Take(int)
instead of First()
... I just don't know what to do. 我尝试使用
this.NoteDatas
而不是issue.NoteDatas
并手动应用id过滤器,我尝试选择第一个笔记,然后获取id(与上面输入的内容相反),尝试使用Take(int)
而不是First()
...我只是不知道该怎么办。 The LINQ reads more straightforward than the SQL it generates. LINQ读取比生成的SQL更直接。
By this: 这样:
join original in this.NoteDatas on issue.NoteDatas
.OrderBy(n => n.CreatedDate)
.Select(n => n.NoteId)
.First() equals original.NoteId
you are saying "order by CreatedDate, take first row from the results and check if it equals to NoteId". 您说的是“按CreatedDate排序,从结果中获取第一行,并检查其是否等于NoteId”。 This is correctly gets rendered to this:
正确地渲染到此:
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]
so t2.id
is always same for any outer [t1].[id]
but depends on only [t0].[IssueDetailsId]
因此,对于任何外部
[t1].[id]
, t2.id
始终相同,但仅取决于[t0].[IssueDetailsId]
Sample: 样品:
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()
});
This is how I ended up changing the LINQ to have it work: 这就是我最终更改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 }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.