6

在我的应用程序中,一家公司可以有很多员工,每个员工可能有多个电子邮件地址。

数据库模式将这些表关联起来,如下所示:

公司 -> CompanyEmployeeXref -> 员工 -> EmployeeAddressXref -> 电子邮件

我正在使用实体框架,我想创建一个 LINQ 查询,该查询返回公司名称和逗号分隔的员工电子邮件地址列表。这是我正在尝试的查询:


from c in Company
join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
join e in Employee on ex.EmployeeId equals e.Id
join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
join a in Address on ax.AddressId equals a.Id
select new {
              c.Name,
              a.Email.Aggregate(x=>x + ",")
           }


期望的输出:

"公司 1", "a@company1.com,b@company1.com,c@company1.com"

"公司 2", "a@company2.com,b@company2.com,c@company2.com"

...

我知道这段代码是错误的,我想我错过了一个 group by,但它说明了这一点。我不确定语法。这甚至可能吗?谢谢你的帮助。

4

2 回答 2

7

现在我解决了这个问题:


from c in Company
join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
join e in Employee on ex.EmployeeId equals e.Id
join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
join a in Address on ax.AddressId equals a.Id
group a.Email by new {c.Name} into g
select new {
                Company=g.Key.Name,
                Email=g.Select(e=>e).Distinct()
            }
).ToList()
.Select(l=> 
           new {
                    l.Name,
                    Email=string.Join(",", l.Email.ToArray())
                }
        )


于 2010-05-18T22:29:04.787 回答
5

实际上,在纯 Linq to SQL(或实体框架,无论您使用哪个)中执行此操作相当困难,因为 SQL Server 本身没有任何可以生成逗号分隔列表的聚合运算符,因此它无法转换将整个语句合并为一个查询。我可以给你一个“单语句”Linq to SQL 的答案,但它实际上不会给你很好的性能,而且我不确定它是否会在 EF 中工作。

如果您只是进行常规连接,将结果具体化,然后使用 Linq to Objects 进行连接,那就更难看了,但仍然更好:

var rows =
    (from c in Company
     join ex in CompanyEmployeeXref on c.Id equals ex.CompanyId
     join e in Employee on ex.EmployeeId equals e.Id
     join ax in EmployeeAddressXref on e.Id equals ax.EmployeeId
     join a in Address on ax.AddressId equals a.Id
     select new 
     {
         c.Name,
         a.Email
     }).AsEnumerable();

var emails =
    from r in rows
    group r by r.Name into g
    select new
    {
        Name = g.Key,
        Emails = g.Aggregate((x, y) => x + "," + y)
    };
于 2010-05-18T21:31:09.777 回答