LINQ to SQL - 将子连接到父级(相同表)

时间:2015-03-07 23:15:20

标签: c# sql asp.net-mvc linq-to-sql

出于某种原因,我很难想到如何做到这一点。

我有一张消息帖子表。 (它是一个非常大的现有遗留系统的一部分,我无法改变表的定义方式。)只有一个帖子表。它是一个两级层次结构。每个帖子都是“父母”或“孩子”。儿童是回复父母的帖子。 (没有其他级别。)

例如,非常简单,可能会有一个Posts表,如下所示:

ID,ParentID,Content,UserID
===========================
1,0,"Hello",3
2,1,"Reply to Hello",7
3,1,"Another Reply to Hello",4
4,0,"New Post",2
...etc...

所以想象一下,非常简单的Posts表定义如下:

INT ID [identity value for the post],
INT ParentID [0 == no parent, otherwise the value is the parent identity value]
TEXT Content [just imagine it is text]
INT UserID [the author of the post]

这是问题所在。我想找到对特定用户的所有回复。

所以,例如,如果我想查找上面对UserID#3所做的所有回复,我应该想出这个:

ID,ParentID,Content,UserID
===========================
2,1,"Reply to Hello",7
3,1,"Another Reply to Hello",4

那是因为UserID#3发布了帖子ID#1,而这两个是回复。

通过UserID#3查找所有父帖子很简单。我会这样做:

var posts = (from db.Posts
  where p.UserID == 3
  && p.ParentID == 0 // this is a parent
  select p).ToList();

同样,要查找非UserID#3发布的所有子(回复)帖子,我会这样做:

var posts = (from db.Posts
  where p.UserID != 3
  && p.ParentID != 0 // this is a child
  select p).ToList();

但我如何才能找到仅对UserID#3 ???

进行的所有回复

想象一下,Posts表在过去的10年中有1,000,000行,并且可能只有3行是回复,所以我不能完全将它们全部放入某些List然后进行排序。我需要做1个LINQ to SQL查询,只返回所需的3行。

如果我能做到这一点,它会起作用:

int userId = 3;
var posts = (from p in db.Posts
  where p.UserID != 3
  && p.ParentID != 0 // this is a child
  && DID_USER_CREATE_POST(userId,p.ID) // can't do this -- since this imaginary C# function won't work here
  select p).ToList();

我想我需要做一些自连接(???),因为父和子在同一个表中,想出那3行所需的行...但我还没弄明白使用现有的表结构执行此操作。

有没有人知道如何使用LINQ to SQL实现这一目标。我正在使用C#,代码将在ASP.NET MVC控制器中(发出RSS)。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

我没有像你一样对这样的数据结构进行过尝试,但它可能会让你到达那里:

var id = 3;
var query =
from p in db.Posts
join r in db.Posts on p.ID equals r.ParentId
where p.UserId == id && p.ParentId == 0
select new { Post = p, Reply = r};

答案 1 :(得分:0)

如果你有正确的外键设置,LINQ应该看到引用,所以你的查询将是这样的。

var posts = from p in db.Posts
  where p.Parent != null //Looking for children only
  && p.Parent.UserId == 3 //UserId of the parent post

可能会以不同方式调用引用对象。如果您没有看到任何此类对象,您也可以通过连接实现相同的功能。

from post in db.Posts
join parent in db.Posts on post.ParentId equals parent.ID
where parent.UserId == 3
select post

我省略了其他更简单的where子句。