2011-03-08 69 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