![](/img/trans.png)
[英]LEFT JOIN or RIGHT JOIN using LINQ Entity-Framework
[英]Left join using a different or not equal in Entity Framework
我必須建立一個查詢來獲取未收到的用戶並提醒新帖子。
我的相關表結構如下:
帖子:postId int用戶:userId int,電子郵件varchar PostAlertUsers:postAlertUserId int,postId int,userId int
表之間的所有相關字段都有FK約束。
我已經在SQL中建立了此查詢,但是找不到在Entity Framework中工作的方法:
SELECT u.email
FROM Users u
INNER JOIN Posts p ON p.userId != u.userId
LEFT JOIN PostAlertUsers pu ON u.userId = pu.userId AND p.postId = pu.postId
WHERE pu.postAlertUserId IS NULL
我編寫了以下EF查詢,但沒有得到相同的結果:
from u in context.Users
join pu in context.PostAlertUsers on u.userId equals pu.userId into postAlerts
from pa in postAlerts.DefaultIfEmpty()
join p in context.Posts on pa.postId equals p.postId
where pa.userId != u.userId
select u.email;
我如何使用linq到實體獲得相同的結果。 使用點語法(我不知道DbSet.Where(x => ...)
語法的正確術語)會更好。
編輯:
我想這並沒有對記錄所有用戶PostAlertUsers
每個Post
的Posts
不是來自同一個用戶。
編輯2:
嘗試澄清更多:
我只想警告用戶有關其他用戶的新帖子,每個帖子一次,我的例程將每小時運行一次,以檢查是否有任何人要發送消息。
我想讓所有尚未收到帖子警告的用戶,因此該用戶和帖子組合在PostAlertUsers
上沒有記錄,但其他用戶在Posts上有記錄。
示例數據:
Users
------------------------
userid | email
------------------------
1 | email1@test.com
2 | email2@test.com
3 | email3@test.com
------------------------
Posts (posts are created by users)
------------------------
postId | userId
------------------------
1 | 1
2 | 3
3 | 1
------------------------
PostAlertUsers (every time a user is notified about a new post, one record is added here)
------------------------
postId | userId
------------------------
1 | 2
1 | 3
2 | 1
------------------------
結果查詢將輸出以下數據:
Result (using postId and userId to identify what user have to be notified for what post)
---------------------------------
postId | userId | email
---------------------------------
2 | 2 | email2@test.com
3 | 2 | email2@test.com
3 | 3 | email3@test.com
---------------------------------
編輯:
感謝AD.Net,我提出了以下建議:
from u in context.Users
let posts = contexto.Posts.Where(p => p.userId != u.userId)
from p in posts
join pau in context.PostAlertUsers on u.userId equals pau.userId
into alerts
from a in alerts.DefaultIfEmpty()
where a == null || a.postId != p.postId
orderby p.idPost
select new {
p.postId,
u.userId,
u.email
}
編輯:從不同角度進行另一次嘗試(不確定性能)可能與cross-join
聯接一樣糟糕
from p in context.Posts
let otherUsers = context.Users.Where(u => u.UserId != p.User.UserId)
from u in otherUsers
join pau in alerts on u.UserId equals pau.User.UserId into alert
from a in alert.DefaultIfEmpty()
where a == null || a.Post.PostId != p.PostId
select new {p.PostId, u.Email};
這是LinqPad的嘗試:
void Main()
{
var users = new List<User>{new User{UserId = 1}, new User{UserId = 2}};
var posts = new List<Post>
{
new Post{PostId = 1, User = new User{UserId = 2}},
new Post{PostId = 2, User = new User{UserId = 1}},
new Post{PostId = 3, User = new User{UserId = 2}},
};
var alerts = new List<PostUserAlert>
{
new PostUserAlert{Post = new Post{PostId = 1},
User = new User{UserId = 1}}
};
var result = (from p in posts
let otherUsers = users.Where(u => u.UserId != p.User.UserId)
from u in otherUsers
join pau in alerts on u.UserId equals pau.User.UserId into alert
from a in alert.DefaultIfEmpty()
where a == null || a.Post.PostId != p.PostId
select new {p.PostId, u.UserId}).ToList();
result.Dump();
}
class User
{
public int UserId { get; set; }
public string Email { get; set; }
}
class Post
{
public int PostId { get; set; }
public User User { get; set; }
public List<PostUserAlert> PostUserAlerts { get; set; }
}
class PostUserAlert
{
public Post Post { get; set; }
public User User { get; set; }
}
// Define other methods and classes here
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.