2013-05-05 87 views
4

你好,我有一些问题创建一个复杂的Linq与多联接和左联接。需要帮助创建复杂的ef linq选择

我有最后列出的4个表,这是用来看我需要发送一个电子邮件有关的主题的新答复。所以我从用户加入的主题中获取所有帖子。同一个用户可能因为每个主题中有超过1个帖子而停止使用。 之后,我加入UserEmailSetting,这是为了查看用户是否已经开始收回电子邮件通知。最后,我需要知道一封电子邮件是否已发送给用户,通知有关新回复(如果发送了很多回复,我不想让用户发送垃圾邮件),所以如果自上次发送回复通知访问该网站我不想发送另一封邮件。这是我的尝试,但我想试试它! 问题是,UserEmailSetting上可能会有很多结果,所以当我发现只有1或2回的时候,我得到了很多结果。

这里是我的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(); 

这里是数据库类

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公司:什么,我想LINQ做更有条理的一个位布局,我希望它可以帮助

  • 获取ForumPostRepository的所有帖子,其中topicId是13
  • 与UserRepository加入上ForumPostRepository.UserId = UserRepository.Id
  • 现在我只希望unike用户
  • 与UsersEmailSettingRepository加入上UserRepository.Id = UsersEmailSettingRepository.UserId
  • LEFT JOIN与EmailLogRepository上UserRepository.Id = EmailLogRepository.UserId AND EmailLogRepository.Type = “ReplyToTopic”AND EmailLogRepository.Values =“topicId”
  • - >现在可以有任何地方从0到*这个请求的结果,我只想要最新!
+0

有时候,最好只写SQL,而不是尝试做这样的事情。 – Phill 2013-05-06 02:56:35

+0

你可以显示你的类中有哪些导航属性? – 2013-05-06 06:53:39

+0

我使用重复模式,因此我无权访问导航属性。我会在2分钟内更新问题。 – Androme 2013-05-06 08:29:33

回答

2

不保证这将是高性能的。

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; 

签名

一个LINQ忍者

编辑:刚才看到你没有导航属性。

+0

谢谢你会在我回家的时候试试 – Androme 2013-05-06 09:00:55

+0

我已经尝试过了,但它不起作用:(我认为linq本身是有效的,但是我不认为EF知道如何翻译它! 代码:http:// pastebin.com/XGJhJFdi错误:http://i.imgur.com/asHjXJr.png – Androme 2013-05-06 12:51:56

+0

呃......呃......叹了口气......典型的......这个应该可以解决它的道歉我忘了关闭IQueryable与Repository.Get()Func相反,尽管我警告你有几个EF-Linq提供程序不能工作,比如MySQL,但它应该可以工作。 – Aron 2013-05-06 15:35:27