LINQ:左连接和右连接双选

问题描述 投票:0回答:2

我正在寻找一个解决方案,在下面的LINQ查询中包含表PART的所有内容(通过添加我认为的右/左连接):

var query = (from p in db.PARTS
             join oc in db.OUTPUT_CONTROLS on p.id equals oc.partid
             join f in db.FCT on p.fct equals f.id
             select new
             { p.id, p.plant, p.unit, p.type, p.num, f.name, oc.datetime, oc.ncr } 
             into x
             group x by new 
             { x.id, x.plant, x.unit, x.type, x.num, x.name } 
             into g
             select new 
             { g.Key.id, g.Key.plant, g.Key.unit, g.Key.type, g.Key.num, g.Key.name, startdate = g.Min(oc => oc.datetime), endate = g.Max(oc => oc.datetime), sumncr = g.Sum(oc => oc.ncr) })
             .OrderByDescending(oc => oc.startdate);

谢谢

c# .net sql-server linq
2个回答
0
投票

如果您有一个SQL,其中您看到一个连接后跟一个GroupJoin,请考虑使用LINQ GroupJoin。

在你想要“学生与他们的学生”,“顾客与他们的订单”,“动物与动物的动物园”的情况下,你会经常看到这一点

您似乎有3个表:零件,输出控件和事实。

每个Part都有零个或多个OutputControls,每个OutputControl都属于一个Part,使用外键PartId:一个简单的一对多关系

Part有一个外键FctId,指向该部分的Fct。

你想要(部分属性)部件,其OutputControls和它的Fct

var result = parts.GroupJoin(outputControls,   // GroupJoin Parts and OutputControls
    part => part.Id,                           // from every part take the Id
    outputControl => outputControl.PartId,     // from every outputControl take the PartId

    // result selector: when these Ids match,
    // use the part and all its matching outputControls to make one new object:
    (part, outputControlsOfThisPart) => new
    {
        // select the part properties you plan to use:
        Id = part.id,
        Plant = part.plant,
        Unit = part.unit

        // the output controls of this part:
        OutputControls = outputControlsOfThisPart.Select(outputControl => new
        {
             // again, select only the output control properties you plan to use
             Id = outputControl.Id,
             Name = outputControl.Name,
             ...
        })
        .ToList(),

        // For the Fct, take the Fct with Id equal to Part.FctId
        Fct = Fcts.Where(fct => fct.Id == part.Fct)
                  .Select(fct => new
                  {
                      // select only the Fct properties you plan to use
                      Id = fct.Id,
                      Name = fct.Name,
                      ...
                  })
                  // expect only one such Fct
                  .FirstOrDefault(),
    });

1
投票

由于这篇文章,我自己找到了解决方案:LINQ Left Join And Right Join

解决方案 :

var query = (from p in db.PARTS
                             join oc in db.OUTPUT_CONTROLS on p.id equals oc.partid into joined
                             join f in db.FCT on p.fct equals f.id
                             from j in joined.DefaultIfEmpty()
                             select new
                             { p.id, p.plant, p.unit, p.type, p.num, f.name, j.datetime, j.ncr } into x
                             group x by new { x.id, x.plant, x.unit, x.type, x.num, x.name } into g
                             select new { g.Key.id, g.Key.plant, g.Key.unit, g.Key.type, g.Key.num, g.Key.name, startdate = g.Min(oc => oc.datetime), endate = g.Max(oc => oc.datetime), sumncr = g.Sum(oc => oc.ncr) })
                             .OrderByDescending(oc => oc.startdate);
© www.soinside.com 2019 - 2024. All rights reserved.