Hello i am having some problems creating an complex Linq with multible joins and left joins.
I have 4 tables as listed in the end, what this is used for is to see how i need to send an email about a new reply to a topic. So i fetch all Posts from the topic joined by the user. The same user can ofcause have more then 1 post in each topic. After that i join with UserEmailSetting, this is to see if the user have oped out reciving email notifications. Lastly i need to know if an email have been send to the user notifying about the new reply (I don't want to spam my users if there are made a lot of replys), so if an reply notification have been sendt since the last visit to the site I don't want to send another mail. Here is my try that works, but i would like to optimate it! The problem is that there can be many results on the UserEmailSetting, so i get alot os results back when i infact only get 1 or 2 back.
here is my attept
var select = (from p in ForumPostRepository.Get()
join u in UserRepository.Get() on p.UserId equals u.Id
join ues in UsersEmailSettingRepository.Get() on u.Id equals ues.UserId
join els in
(from _el in EmailLogRepository.Get()
where _el.Type == "ReplyToTopic" &&
_el.Values == topicId
orderby _el.Id descending
select _el) on u.Id equals els.UserId
into emailLogs
from el in emailLogs.DefaultIfEmpty()
where p.TopicId == forumTopic.Id &&
ues.ReplyToTopic //&& // We only want people who need notifications
//!u.Online // We only want people who are not online
orderby p.Id descending, el.Id descending
select new
{
User = u,
EmailLog = el
});
var result = select.DistinctBy(x => x.User.Id).ToList();
Here are the database classes
public class ForumPost
{
public int? TopicId { get; set; }
public int UserId { get; set; }
...
}
public class User
{
public int Id { get; set; }
public bool Online { get; set; }
public DateTime LastLogin { get; set; }
...
}
public class UsersEmailSetting
{
public int UserId { get; set; }
public bool ReplyToTopic { get; set; }
}
public class EmailLog
{
public int Id { get; set; }
public int UserId { get; set; }
public string Type { get; set; }
public string Values { get; set; }
public DateTime Created { get; set; }
}
Updata: a bit more structured layout of what i want the linq to do, I hope It helps
No guarantees that this will be performant.
var users = UserRepository.Get();
var userEmailSettings = UsersEmailSettingRepository.Get();
var emailLogs = EmailLogRepository.Get();
var posts = ForumPostRepository.Get();
var foo =
from user in users
where posts
.Any(post => post.UserId == u.Id && post.TopicId == topicId)
where userEmailSettings
.Any(ues => u.Id equals ues.UserId && ues.ReplyToTopic == true)
where false ==
(
from el in emailLogs
where el.Type == "ReplyToTopic"
&& el.Values == topicId
&& el.UserId == user.Id
&& el.Created > user.LastLogin
select el
).Any()
select user;
Signed
A Linq Ninja
edit: just saw that you don't have navigation properties.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.