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
子句。
出于某种原因,我很难思考如何做到这一点。
我有 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
子句。