linq中的联合3表和具有最大id的嵌套表的返回值

时间:2016-08-03 14:58:34

标签: c# sql-server linq join

我有桌子,你可以看到:

行:

id       Linename
1        line1
2        line2
3        line3

关节:

id       lineId   jointname
1        1        joint1
2        2        joint2
3        1        joint3

fitup:

id      jointid    fitupdate     state
1       1          2012/12/12    acc
2       1          2013/12/12    rej
3       2          2015/12/12    acc
4       2          2016/12/12    rej

我需要的结果:

id     Linename      jointname    fitupdate     state
1      line1          joint1      2013/12/12    rej
2      line2          joint2      2016/12/12    rej

装配表有state我需要基于最大ID的最终状态。

在装配表中,每个关节都有多行,但我需要在结果查询中使用max id的日期(字符串)。

这是我的问题:

var q = from j in _ctx.Joints
    join l in _ctx.Lines on j.LineId equals l.Id
    join spo in _ctx.Spools on j.SpoolId equals spo.Id
    join sup in _ctx.Supports on j.SupportId equals sup.Id
    join shee in _ctx.Sheets on j.SheetId equals shee.Id
    join Fit in _ctx.FitUpDetails on j.Id equals Fit.JointId into g2
    from y2 in g2.DefaultIfEmpty()

    join weld in _ctx.WeldDetails on j.Id equals weld.JointId into g
    from y1 in g.DefaultIfEmpty()
    join end in _ctx.Ends on j.EndId equals end.Id

    join basemat in _ctx.BaseMaterials on j.BaseMaterialId equals basemat.Id
    join TestPack in _ctx.TestPackages on j.TestPackageId equals TestPack.Id

    group new { j, l,y2,y1} by new { shee, j, l, spo, sup, y2, y1, end, basemat, TestPack } into grouping
    let maxFitById = grouping.Select(item => item.y2)
                     .Where(item => item != null)
                     .OrderByDescending(item => item.Id)

    let maxweldById = grouping.Select(item => item.y1)
   .Where(item => item != null)
   .OrderByDescending(item => item.Id)

    select new ViewFront()
    {
        Id = grouping.Key.j.Id,
        LineId = grouping.Key.l.LineNumber,
        SubmitDateTime = grouping.Key.j.SubmitDateTime,
        JointNumber = grouping.Key.j.JointNumber,
        BaseMaterialId = grouping.Key.basemat.Name,
        FitUpAccept = maxFitById.FirstOrDefault().StateStep1,
        FitUpAcceptMain = maxFitById.FirstOrDefault().StateStep2,
        JointClass = grouping.Key.j.JointClass,
        End = grouping.Key.end.Name,
        JointSize = grouping.Key.j.JointSize,
        LeftMaterialItemCode = grouping.Key.j.LeftMaterialItemCode,
        LeftMaterialLength = grouping.Key.j.LeftMaterialLength.ToString(),
        MagneticTest = grouping.Key.j.MagneticTest,
        PenetrationTest = grouping.Key.j.PenetrationTest,
        PostWeldHeatTreatment = grouping.Key.j.PostWeldHeatTreatment,
        RemarkState = grouping.Key.j.RemarkState,
        RightMaterialItemCode = grouping.Key.j.RightMaterialItemCode,
        RightMaterialLength = grouping.Key.j.RightMaterialLength.ToString(),
        RadiographyTest = grouping.Key.j.RadiographyTest,
        SheetId = grouping.Key.shee.SheetNumber,
        ShopField = grouping.Key.j.ShopField,
        SpoolId = grouping.Key.spo.SpoolNumber,
        SupportId = grouping.Key.sup.SupportNumber,
        TestPackageId = grouping.Key.TestPack.PackageNumber,
        THK = grouping.Key.j.THK,
        UltrasonicTest = grouping.Key.j.UltrasonicTest,
        WeldAccept = maxweldById.FirstOrDefault().StateStep1,
        WeldAcceptMain = maxweldById.FirstOrDefault().StateStep2
    };

在此查询中,FitUpAccept是州。

联合表数据 virtual environment

焊接: enter image description here

fitup: enter image description here

结果: enter image description here

1 个答案:

答案 0 :(得分:2)

以下代码可满足您的需求。现在有一些解释:

  1. 我只保留与所描述的输出数据相关的表格,以保持简单。
  2. grouping by时 - 如果您像往常一样选择整个对象,那么您将始终获得单个记录的“组” - groupkey所需的数据 - 在这种情况下,非聚合字段。确保您没有按照您希望实际进行聚合操作的相同字段进行分组(例如y2)
  3. 因为它是left join的{​​{1}}我必须确保删除所有FitUpDetails记录,并且每次访问该对象的属性时都要确保它不为null - null的c#6.0语法。
  4. 现在,对于 By max id 部分 - 如果我将其分为单词:“按X对数据进行分组,然后对于按Y排序的每个组,请取第一个记录 - >其属性“
  5. 所以代码:

    ?.

    用它来测试它:

    var result = (from j in Joints
                  join l in Lines on j.LineId equals l.Id
                  join f in FitUpDetails on j.Id equals f.JointId into g2
                  from y2 in g2.DefaultIfEmpty()
    
                  group new { j, l, y2 } by new { j.Id, l.LineName, j.JointName } into grouping
    
                  let maxFitById = grouping.Select(item => item.y2)
                                          .Where(item => item != null)
                                          .OrderByDescending(item => item.Id)
                                          .FirstOrDefault()
    
                  select new
                  {
                      Id = grouping.Key.Id,
                      LineName = grouping.Key.LineName,
                      JointName = grouping.Key.JointName,
                      FitUpdate = maxFitById?.FitUpdate,
                      State = maxFitById?.State
                  }).ToList();