2013-05-05 63 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