繁体   English   中英

将简单的Left Outer Join和group by SQL语句转换为Linq

[英]Convert simple Left Outer Join and group by SQL statement into Linq

2个表:用户和警报

表:用户 UserID(int),FullName(varchar)

表:Alarm AssignedTo(int),已解决(bool)

查询:

SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved, COUNT(resolved) -  SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname

结果:

Fullname  Assigned  Resolved  Unresolved
User1     204       4         200
User2     39        9         30
User3     235       200       35
User4     1         0         1
User5     469       69        400

对于我的生活,我无法弄清楚如何将其变成Linq查询。 我在分组功能方面遇到了麻烦。 我看了无数的例子,没有我的左外连接与分组的组合,或者它们是如此复杂以至于我无法弄清楚如何使它与我一起工作。 这里的任何帮助将非常感谢!!!

更新:我可能不清楚我在寻找什么。 我正在寻找由AssignedTo列分组的警报,这是一个用户ID ...除了,我想用user表中的FullName替换该用户ID。 有人发布并删除了一些关闭的东西,除了它给了我在用户表中的所有用户,这不是我正在寻找的..

更新2:请参阅下面的答案

假设您有以下型号:

这是警报的模型:

public class Alarm
{
    public int id { get; set; }

    public int AssignedTo { get; set; }

    [ForeignKey("AssignedTo")] 
    public virtual User User { get; set; }

    public bool Resolved { get; set; }
}

这是用户的模型:

public class User
{
    public int UserID { get; set; }

    public string FullName { get; set; }

    public virtual ICollection<Alarm> Alarms { get; set; }

    public User()
    {
        Alarms = new HashSet<Alarm>();
    }
}

这是保存每个用户的警报统计信息的模型:

public class UserStatistics
{
    public string FullName { get; set; }
    public int Assigned { get; set; }    
    public int Resolved { get; set; }    
    public int Unresolved { get; set; }    
}

然后,您可以执行以下操作:

var query = context.Users.Select(
    user =>
        new UserStatistics
        {
            FullName = user.FullName,
            Assigned = user.Alarms.Count,
            Resolved = user.Alarms.Count(alarm => alarm.Resolved),
            Unresolved = user.Alarms.Count(alarm => !alarm.Resolved)
        });


var result = query.ToList();

顺便说一句,您还可以修改查询并删除Unresolved = user.Alarms.Count(alarm => !alarm.Resolved) ,然后将Unresolved属性设置为如下计算属性:

public class UserStatistics
{
    public string FullName { get; set; }
    public int Assigned { get; set; }    
    public int Resolved { get; set; }    
    public int Unresolved
    {
        get { return Assigned - Resolved; }
    }
}

这将使生成的SQL查询更简单。

我终于弄明白了。

这个:

var results = alarms.GroupBy(x => x.AssignedTo)
.Join(users, alm => alm.Key , usr => usr.UserID, (alm, usr) => new {
    Fullname = usr.FullName,AssignedNum = alm.Count(),
    Resolved = alm.Where(t=>t.resolved == true).Select(y => y.resolved).Count(), 
    Unresolved = alm.Where(t=>t.resolved == false).Select(y => y.resolved).Count() });

再现这个:

SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved, 
       COUNT(resolved) -  SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname

结果按AssignedTo(int)分组,但未选择AssignedTo。 而是从连接的用户表中选择FullName。

非常感谢所有试图帮助的人! 我从你的答案中学到了很多东西。

对于奖励积分,我如何用SQL语法编写我的lamdbda答案?

尝试这个 :

from u in context.User
join a in context.Alarm on u.UserID equals a.AssignedTo into g1
from g2 in g1.DefaultIfEmpty()
group g2 by u.Fullname into grouped
select new { Fullname = grouped.Key, Assigned = grouped.Count(t=>t.Resolved != null), Resolved = grouped.Sum
                                    (t => int.Parse(t.Resolved)), Unresolved = (grouped.Count(t=>t.Resolved != null) - grouped.Sum
                                    (t => int.Parse(t.Resolved)))}

我想在Linq中不一定要对此查询使用“分组”,因为“LEFT JOIN”+“GROUP BY”的组合将它们更改为“INNER JOIN”。

    var results =
        from u in users
        join a in alarms on u.UserID equals a.AssignedTo into ua
        select new
        {
            Fullname = u.FullName,
            Assigned = ua.Count(),
            Resolved = ua.Count(a => a.Resolved),
            Unresolved = ua.Count(a => !a.Resolved)
        };

        foreach (var r in results)
        {
            Console.WriteLine(r.Fullname + ", " + r.Assigned + ", " + r.Resolved + ", " + r.Unresolved);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM