簡體   English   中英

在實體框架中使用不同或不相等的左聯接

[英]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每個PostPosts不是來自同一個用戶。

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM