简体   繁体   English

需要帮助创建复杂的EF LINQ选择

[英]Need help creating complex ef linq select

Hello i am having some problems creating an complex Linq with multible joins and left joins. 您好,我在创建具有多重联接和左联接的复杂Linq时遇到一些问题。

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. 我最后列出了4个表格,这用于查看我需要如何发送有关主题的新回复的电子邮件。 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. 同一用户可能在每个主题中发表超过1条帖子。 After that i join with UserEmailSetting, this is to see if the user have oped out reciving email notifications. 之后,我与UserEmailSetting一起加入,以查看用户是否选择了接收电子邮件通知。 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. 问题是,UserEmailSetting上可能有很多结果,因此当我实际上只得到1或2时,我会得到很多OS结果。

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 Updata:我希望linq进行的结构化布局,希望对您有所帮助

  • Get all posts from ForumPostRepository where topicId is 13 从topicId为13的ForumPostRepository获取所有帖子
  • Join with UserRepository on ForumPostRepository.UserId = UserRepository.Id 在ForumPostRepository.UserId = UserRepository.Id上与UserRepository一起加入
  • Now I only want unike users 现在我只想要unike用户
  • Join with UsersEmailSettingRepository on UserRepository.Id = UsersEmailSettingRepository.UserId 通过UserRepository.Id = UsersEmailSettingRepository.UserId上的UsersEmailSettingRepository加入
  • Left join with EmailLogRepository on UserRepository.Id = EmailLogRepository.UserId AND EmailLogRepository.Type = “ReplyToTopic” AND EmailLogRepository.Values = “topicId” 与UserRepository.Id = EmailLogRepository.UserId和EmailLogRepository.Type =“ ReplyToTopic” AND EmailLogRepository.Values =“ topicId”上的EmailLogRepository左联接
  • -> Now there can be anywhere from 0 to * results on this request, I only want the latest! ->现在,此请求可以有0到*个结果,我只想要最新的!

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. 编辑:只是看到您没有导航属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM