显示不相关表的合并结果(linq to sql)

发布于 2024-10-21 01:28:10 字数 2368 浏览 1 评论 0原文

我正在努力找出使用 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;
}

谢谢,

安妮莉

I'm struggling to work out the best way to show a combined result from two unrelated tables using linq to sql (C#). The tables are EmailAlerts and TextAlerts, each with UserName, Type and Status (plus other columns that differ, but only need these three for this query). For reporting purposes, I need to get a snapshot of users who have an active alert in the system.

Example tables:

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

This will be put in a csv file, and the final result for the example tables should look like this:

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

So, for each unique user, find out if they have an active (status = 0) email or text alert of either type. They can have multiple alerts for both types. The users are stored in Sitecore so there is no user table.

At the moment I'm first getting all the unique usernames, then looping through each one to find out what alerts they have. It works, but it's pretty horrible so I'd like to find a better solution. Is it possible to do it all in one query? Would a stored procedure be a better way of doing it? If anyone can point me in the right direction I can try to figure out the code myself, I'm just not sure of best way to tackle it.

UPDATE: Here's the current (ugly) code:

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

Thanks,

Annelie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹雪碎 2024-10-28 01:28:10

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

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

这对您有帮助吗?

Try this out, if anything it might give you an idea. My idea behind it is to use correlated subqueries a new anonymous type to store all the information you need.
Check it out:

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

Does this provide any help to you?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文