我有3个实体,Computer,Monitor和PortNumber。实体监视器具有引用实体计算机的外键,而实体PortNumber具有引用实体Monitor的外键。以下规则适用
我想编写一个Join来显示每台计算机的监视器和端口(监视器端口)的数量。我可以使用groupjoin加入两个实体,但无法弄清楚如何添加第三个实体。
var v = Ports.GroupJoin(Monitors, c => c.ComputerId, m => m.ComputerId,
(c, m) => new{c, m})
.select(s => new {
Computer = c.ComputerProp,
Monitors = m.Sum()});
如何添加第3个实体? 以下是一些可执行代码:http://dotnetfiddle.net/L1TBgJ
答案 0 :(得分:1)
var v =
from c in Computers
// First outer join.
join m in Monitors on c.ComputerId equals m.ComputerId into monitor
from m in monitors.DefaultIfEmpty()
// Second outer join.
join p in Ports on m.PortId equals p.PortId into port
from p in port.DefaultIfEmpty()
// Group by the computers
group new { m, p } by new { c } into g
select new
{
Computer = g.Key.c,
Monitors = g.Select(i => i.m).Distinct().ToList(),
Ports = g.Select(i => i.p).Distinct().ToList(),
};
我认为这是你要找的东西。第二个连接意味着您需要确保对未包含在分组中的项目调用distinct。如果监视器对象上存在端口集合。然后你只需要嵌套查询的第二部分。
如果端口是显示器上的集合,并且您希望将它们展平以链接到计算机。我认为这样的事情应该这样做。
var v =
from c in Computers
// First outer join.
join m in Monitors on c.ComputerId equals m.ComputerId into monitor
from m in monitors.DefaultIfEmpty()
// Group by the computers
group new { m } by new { c } into g
select new
{
Computer = g.Key.c,
Ports = g.Select(i => i.m).SelectMany(i => i.Port).ToList(),
};
答案 1 :(得分:1)
由于您在EF模型中正确设置了关联,因此根本不需要连接。你应该能够这样做:
var v = Computers
.Select(c => new {
Computer = c.ComputerProp,
Monitors = c.monitors.Count(), // note: not Sum(),
Ports = c.monitors.Sum(m => m.ports.Count())
});
我在您的测试脚本中注意到您正在使用对象,您没有实例化监视器和端口阵列并将它们设置为您添加的对象。如果你正在使用代码优先EF(我怀疑你是),那么在实际向数据库发出查询时将设置这些值。