【问题标题】:Show combined result from unrelated tables (linq to sql)显示不相关表的组合结果(linq to sql)
【发布时间】:2011-03-08 18:41:01
【问题描述】:

我正在努力找出使用 linq to sql (C#) 显示两个不相关表的组合结果的最佳方法。这些表是 EmailAlerts 和 TextAlerts,每个都有 UserName、Type 和 Status(加上其他不同的列,但此查询只需要这三个)。出于报告目的,我需要获取系统中具有活动警报的用户的快照。

示例表:

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;
}

谢谢,

安妮莉

【问题讨论】:

  • 您能否向我们展示您要实现的目标的代码,也许它会给我们一个提示?这样一来,目标就有点不清楚了。
  • @bojanskr - 添加了示例表,还将添加 linq to sql 代码我到目前为止,但请注意,它闻起来! :)
  • 没问题,我只想帮忙,不批评:)
  • 我已经更正了解决方案,请查看下面的编辑答案

标签: c# sql linq-to-sql stored-procedures multiple-tables


【解决方案1】:

试试这个,如果有的话,它可能会给你一个想法。我的想法是使用相关子查询一种新的匿名类型来存储您需要的所有信息。 看看吧:

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. */ 
    }

这对您有帮助吗?

【讨论】:

  • 抱歉,我不清楚,将使用示例表更新我的问题。用户不必在两个表中都有记录。
  • 这看起来更好,我一直在尝试将它变成一两个大查询,但这可能是解决它的最佳方法。感谢您的帮助!
猜你喜欢
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多