2016-08-03 14 views
2

Ich habe es Tabellen wie Sie sehen können:Gelenk 3 Tabellen in Linq und Rückgabewert von verschachtelter Tabelle mit max id

line:

id  Linename 
1  line1 
2  line2 
3  line3 

Gelenk:

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 

Ergebnis ich brauche:

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

Die fitup Tabelle hat eine state ich den Endzustand müssen basierend auf max id.

In der Fitup-Tabelle habe ich mehrere Zeilen für jedes Gelenk, aber ich brauche das Datum (String) von max ID in der Ergebnisabfrage.

Hier ist meine Frage:

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 
    }; 

In dieser Abfrage FitUpAccept ist der Staat.

Gemeinsame Tabellendaten enter image description here

Schweiß: enter image description here

fitup: enter image description here

Ergebnis: enter image description here

Antwort

2

Der folgende Code tut, was Sie brauchen. Jetzt einige Erklärungen:

  1. Ich habe nur die Tabellen, die für die beschriebenen Ausgabedaten relevant sind, nur um es einfacher zu halten.
  2. Wenn grouping by - Wenn Sie die gesamten Objekte als Sie ausgewählt haben, dann erhalten Sie immer "Gruppen" eines einzelnen Datensatzes - I group die gewünschten Daten nur durch die key - In diesem Fall die nicht aggregierten Felder. Stellen Sie sicher, dass Sie nicht nach den gleichen Feldern gruppieren, die Sie tatsächlich aggregieren möchten (wie y2)
  3. Weil es ein left join zu FitUpDetails ist, muss ich sicherstellen, dass ich alle null Datensätze entfernen und wann immer ich Greifen Sie auf eine Eigenschaft dieses Objekts zu, um sicherzustellen, dass es nicht null ist - C# 6.0-Syntax von ?..
  4. Jetzt für die von max id Teil - wenn ich es in Worte zu fassen: „von X die Datengruppierung, und dann für jede Gruppe durch Y, nehmen ersten Datensatz der Bestellung -> seine Eigenschaften“

So zum Code:

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(); 

benutzten es für die Prüfung:

List<dynamic> Joints = new List<dynamic> 
{ 
    new { Id = 1, LineId = 1, JointName = "joint1" }, 
    new { Id = 2, LineId = 2, JointName = "joint2" }, 
    new { Id = 3, LineId = 1, JointName = "joint3" }, 
}; 

List<dynamic> Lines = new List<dynamic> 
{ 
    new { Id = 1, LineName = "line1" }, 
    new { Id = 2, LineName = "line2" }, 
    new { Id = 3, LineName = "line3" }, 
}; 

List<dynamic> FitUpDetails = new List<dynamic> 
{ 
    new { Id = 1, JointId = 1, FitUpdate = new DateTime(2012,12,12), State = "acc" }, 
    new { Id = 2, JointId = 1, FitUpdate = new DateTime(2013,12,12), State = "rej" }, 
    new { Id = 1, JointId = 2, FitUpdate = new DateTime(2015,12,12), State = "acc" }, 
    new { Id = 4, JointId = 2, FitUpdate = new DateTime(2016,12,12), State = "rej" }, 
}; 
+0

Das Problem ist hier: 'new {shee, j, l, spo, sup, y2, y1, Ende,' - wenn du gro Nach dem 'y2' bedeutet dies, dass Sie für jeden Datensatz in der FitUpdate-Tabelle eine andere Gruppe haben - also wenn Sie nur einen Datensatz bestellen - und Ihr Ergebnis wird sowohl" acc "als auch" reg "anzeigen –

+0

Vielen Dank du sehr, sehr lieber Freund –

+0

@Sie sind sehr willkommen :) –