LINQ to SQL - 自连接 Child 到 Parent(相同 Table)

LINQ to SQL - Self Join Child to Parent (Same Table)

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

我有 table 条消息 post。 (它是一个非常大的现有遗留系统的一部分,我无法更改 table 的定义方式。)post 中只有 1 个 table。这是一个 two-level 层次结构。每个 post 要么是 "parent" 要么是 "child"。 Children 正在 post 回复 parent。 (没有其他级别。)

例如,非常简单的帖子 table 可能如下所示:

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...

所以想象一下,一个非常简单的帖子 table 是这样定义的:

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]

问题来了。我想查找对特定用户的所有回复。

所以,例如,如果我想找到对上面的用户 ID #3 的所有回复,我应该想出这个:

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

那是因为 UserID #3 posted post ID #1,这两个是回复。

通过 UserID #3 查找所有 parent post 很简单。我会这样做:

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

同样,要查找所有 child(回复)post 不是由用户 ID #3 创建的,我会这样做:

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

但是我如何才能找到所有只对 UserID #3 做出的回复???

假设帖子 table 在过去 10 年中有 1,000,000 行,并且可能只有 3 行是回复,所以我不能完全将所有这些都强行放入某个列表然后进行排序通过。我需要执行 1 个 LINQ to SQL 查询,仅 returns 需要的 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();

我想我需要做一些 self-join (???),因为 parent 和 child 在同一个 table 中需要的那 3 行..但我还没有弄清楚如何使用现有的 table 结构来做到这一点。

有谁知道我如何使用 LINQ to SQL 完成此操作。我正在使用 C#,代码将在 ASP.NET MVC 控制器(发出 RSS)中。

感谢您的帮助!

我还没有像你这样针对数据结构尝试过这个,但它可能会让你到达那里:

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};

如果您有正确的外键设置,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

引用对象的名称可能不同。如果您没有看到任何此类对象,您也可以通过 join 实现相同的目的。

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

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