2011-03-08 56 views
2

我很努力地找出使用linq to sql(C#)顯示兩個不相關表的組合結果的最佳方法。這些表是EmailAlerts和TextAlerts,每個表都具有用戶名,類型和狀態(加上其他列不同,但只需要這三個查詢)。出於報告目的,我需要獲取系統中具有主動警報的用戶的快照。顯示來自不相關表(LINQ到SQL)的組合結果

示例表:

EmailAlerts 
UserName Type Status 
Alice  1 0 
Alice  1 0 
Alice  1 1 
Alice  2 0 
Alice  2 1 
Alice  2 1 
Bob   1 1 
Bob   2 1 
Mallory  1 1 
Mallory  2 1 

TextAlerts 
UserName Type Status 
Alice  1 1 
Alice  2 0 
Alice  2 1 
Bob   1 0 
Mallory  1 1 
Mallory  2 1 

這將被放置在一個CSV文件,而最終的結果對於例如表應該是這樣的:

Username, ActiveType1Email, ActiveType2Email, ActiveType1Text, ActiveType2Text 
Alice, Yes, Yes, No, Yes 
Bob, No, No, Yes, No 

所以,對於每一個獨特的用戶,看看他們是否有活躍的(狀態= 0)電子郵件或任何一種類型的文字提示。他們可以有兩種類型的警報。用戶存儲在Sitecore中,因此沒有用戶表。

目前我首先獲取所有唯一的用戶名,然後循環查看每個用戶名。它的工作原理,但它非常可怕,所以我想找到一個更好的解決方案。是否可以在一個查詢中完成所有操作?存儲過程會是更好的方式嗎?如果任何人都能指向正確的方向,我可以嘗試自己弄清楚代碼,但我不確定解決這個問題的最佳方式。

更新:這是當前(醜陋的)代碼:

public static List<Dictionary<string, string>> GetUserAlertsForCSV() 
{ 
    List<Dictionary<string, string>> alerts = new List<Dictionary<string, string>>(); 

    var usernames = ((from e in db.EmailAlerts select e.UserName).Union 
        (from t in db.TextAlerts select t.UserName)).Distinct(); 

    foreach (var username in usernames) 
    { 
     Dictionary<string, string> d = new Dictionary<string, string>(); 
     d.Add("username", username); 
     bool hasActiveAlert = false; 

     var activeType1Email = (from e in db.EmailAlerts 
        join a in db.AlertStatusCodes on e.Status equals a.StatusCode 
        where e.UserName == username 
        && e.Type == (int)AlertType.Type1 
        && a.Description == "active" 
        select e).FirstOrDefault(); 

     if (activeType1Email != null) 
     { 
      d.Add("type1email", "Yes"); 
      hasActiveAlert = true; 
     } 
     else 
     { 
      d.Add("type1email", "No"); 
     } 

     // repeat the above for activeType1Text, activeType2Email and activeType2Text 

     if (hasActiveAlert) 
     { 
      alerts.Add(d); 
     } 
    } 

    return alerts; 
} 

感謝,

Annelie

+0

你能告訴我們你正在努力實現的代碼嗎,也許它會給我們一個提示?這樣的目標是不明確的。 – TheBoyan 2011-03-08 19:31:21

+0

@bojanskr - 添加了示例表格,也將linq添加到我迄今爲止的sql代碼中,但被警告,它聞起來! :) – annelie 2011-03-08 19:39:41

+0

沒問題,我只想幫忙,不批評:) – TheBoyan 2011-03-08 19:44:10

回答

2

嘗試了這一點,如果有的話,可能會給你一個想法。我的想法背後是使用相關的子查詢一個新的匿名類型來存儲所有你需要的信息。 檢查出來:

var usernames = ((from e in db.EmailAlerts select e.UserName).Union 
       (from t in db.TextAlerts select t.UserName)).Distinct(); 
var result = 
    from u in usernames 
    select new 
    { 
     Username = u.Username, 
     ActiveType1Email = (from e in db.EmailAlerts 
          where e.UserName == u 
          && e.Type == (int)AlertType.Type1 
          && a.Description == "active" 
          select e).FirstOrDefault(); 
     /* 
     ... and so on repeat for activeType1Text, activeType2Email and activeType2Text 

     */ 
    } 

    // and then go trough the result set which is IEnumarable<T> and use it for what you need 
    foreach(var a in result) 
    { 
     var something = a.ActiveType1Email; 
     /* etc. */ 
    } 

這是否提供給您的任何幫助嗎?

+0

對不起,我還不清楚,會用示例表更新我的問題。用戶不必在兩個表中都有記錄。 – annelie 2011-03-08 19:30:59

+1

這看起來更好,我一直試圖把它變成一兩個大的查詢,但這可能是解決它的最好方法。感謝您的幫助! – annelie 2011-03-10 15:46:19