2016-12-02 8 views
0

Ich habe eine Modellklasse wie folgt.So extrahieren Sie bestimmte Spaltenwerte aus mehreren Zeilen mit linq

Public Class SampleModel 
{ 
    public string ItemName{ get; set; } 
    public string ItemNo{ get; set; } 
    public int ItemQty{ get; set; } 
    public string GroupName{ get; set; } 
    public int Group1 { get; set; } 
    public int Group2 { get; set; } 
    public int Group3 { get; set; } 
    public int Group4 { get; set; } 
} 

Die Tabelle enthält die Werte für die ersten 4 ItemName, ItemNo, ItemQty und GroupName. für jede Art.Nr. sind mit 4 Zeilen und nur werden ItemQty sein unterscheiden sich die von den einzelnen Gruppenname (Group1Count, Group2Count, Group3Count, Groupcount) eingegeben wird.

Tabelleninhalt wie diese.

ItemName ItemNo ItemQty GroupName 
Pen   234 2  Group1 
Pen   234 4  Group2 
Pen   234 6  Group3 
Pen   234 3  Group4 
item2   365 3  Group1 
item2   365 5  Group2 
item2   365 2  Group3 
item2   365 3  Group4 
item3   370 3  Group1 
item3   370 2  Group4 
item4   372 6  Group2 
item4   372 9  Group4 

so bekomme ich alle Werte mit dieser Abfrage.

var data= from a in context.Batch where a.GroupName != "" select a; 

aus dieser wieder muss ich herausfiltern basierend auf der Kombination von ItemName, Art.Nr., ItemQty und zeigen das Ergebnis wie folgt aus.

ItemName ItemNo Group1 Group2 Group3 Group4 
Pen   234  2  4  6  3 
item2  365  3  5  2  3 
item3  370  3  0  0  2 
item4  372  0  6  0  9 

Bitte schlagen Sie mir vor, wie Sie eine linq-Abfrage dafür schreiben.

+0

Sie bauen eine Pivot-Tabelle. Sie haben Glück, dass Sie eine feste Anzahl von Gruppen haben. Bei den meisten Pivot Table-Lösungen ist die Anzahl der Gruppen nicht festgelegt und eine kompliziertere Lösung ist erforderlich. – jdweng

+0

bin sogar nicht so glücklich. Hier kann der Gruppenname zu einer beliebigen Anzahl von Werten gehen. Group1, Group2 ...... Group10 etc .. –

+0

Ich würde die Klasse in öffentliche Liste ändern Groups {get; einstellen; } – jdweng

Antwort

0

können Sie

verwenden
var list=context.Batch.GroupBy(x=>new{x.ItemName,x.ItemNo}) 
          .Select(x=>new 
          { 
            ItemName=x.Key.ItemName, 
            ItemNo=x.Key.ItemNo, 
            Group1=x.Where(y=>y.GroupName=="Group1").FirstOrDefault(), 
            Group2=x.Where(y=>y.GroupName=="Group2").FirstOrDefault(), 
            Group3=x.Where(y=>y.GroupName=="Group3").FirstOrDefault(), 
            Group4=x.Where(y=>y.GroupName=="Group4").FirstOrDefault() 
          }) 
         .Select(x=> new SampleModel{ 
            ItemName=x.ItemName, 
            ItemNo=x.ItemNo, 
            Group1=x.Group1==null?0:x.Group1.ItemQty, 
            Group2=x.Group2==null?0:x.Group2.ItemQty, 
            Group3=x.Group3==null?0:x.Group3.ItemQty, 
            Group4=x.Group4==null?0:x.Group4.ItemQty 

          }).ToList(); 
+0

Zur Laufzeit bekomme diese Ausnahme: Sequenz enthält keine Elemente, obwohl context.Batch alle Werte hat. –

+0

Könnte bitte die Syntax in dieser Zeile. Gruppe 1 = x.Where (y => y.GroupName == "Gruppe 1") FirstOrDefault() == null 0:... X.Where (y => y.GroupName == "Gruppe 1") FirstOrDefault() ItemQty, –

+0

Ich aktualisierte die Antwort. In dieser Variante wähle ich Gruppen aus der Datenbank in der ersten Select-Anweisung aus, danach überprüfe ich in der zweiten Select-Anweisung Gruppenwerte mit einem ternären Operator. Die Bedeutung dieser Anweisung (** x.Group1 == nul? 0: x.Group1 **) ist, dass sie den Wert von group1 überprüft. Wenn der Wert null ist, wird 0 zurückgegeben, andernfalls wird der Wert zurückgegeben. – Eldeniz

0
var data = context.Batch 
    .GroupBy(i => new {i.ItemName, i.ItemNo}) 
    .Select(g => new { 
     ItemName = g.Key.ItemName, 
     ItemNo = g.Key.ItemNo, 
     Group1 = g.Where(i => i.GroupName == “Group1”).First().ItemQty, 
     Group2 = g.Where(i => i.GroupName == “Group2”).First().ItemQty, 
     Group3 = g.Where(i => i.GroupName == “Group3”).First().ItemQty, 
     Group4 = g.Where(i => i.GroupName == “Group4”).First().ItemQty 
    }) 
    .Where(i => i.GroupName != “”); 
+0

Zur Laufzeit bekomme diese Ausnahme: Sequenz enthält keine Elemente, obwohl context.Batch alle Werte hat. –

0

Hier ist die richtige Lösung

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("ItemName", typeof(string)); 
      dt.Columns.Add("ItemNo", typeof(int)); 
      dt.Columns.Add("ItemQty", typeof(int)); 
      dt.Columns.Add("GroupName", typeof(string)); 

      dt.Rows.Add(new object[] {"Pen",234, 2, "Group1"}); 
      dt.Rows.Add(new object[] {"Pen",234, 4, "Group2"}); 
      dt.Rows.Add(new object[] {"Pen",234, 6, "Group3"}); 
      dt.Rows.Add(new object[] {"Pen",234, 3, "Group4"}); 
      dt.Rows.Add(new object[] {"item2",365, 3, "Group1"}); 
      dt.Rows.Add(new object[] {"item2",365, 5, "Group2"}); 
      dt.Rows.Add(new object[] {"item2",365, 2, "Group3"}); 
      dt.Rows.Add(new object[] {"item2",365, 3, "Group4"}); 

      List<string> groupNames = dt.AsEnumerable().Select(x => x.Field<string>("GroupName")).Distinct().ToList(); 

      DataTable pivot = new DataTable(); 
      pivot.Columns.Add("ItemName", typeof(string)); 
      pivot.Columns.Add("ItemNo", typeof(int)); 
      foreach (string groupName in groupNames) 
      { 
       pivot.Columns.Add(groupName, typeof(string)); 
      } 

      var items = dt.AsEnumerable().GroupBy(x => x.Field<string>("ItemName")); 

      foreach (var item in items) 
      { 
       DataRow pivotRow = pivot.Rows.Add(); 
       pivotRow["ItemName"] = item.First().Field<string>("ItemName"); 
       pivotRow["ItemNo"] = item.First().Field<int>("ItemNo"); 
       foreach (var group in item) 
       { 
        pivotRow[group.Field<string>("GroupName")] = group.Field<int>("ItemQty"); 
       } 
      } 
     } 

    } 
} 

enter image description here

+0

Vielen Dank für Ihre Antwort. werde diese Logik versuchen und dich wissen lassen. Ich verwende den Odata-Dienst, um die Daten von der Datenbank (Microsoft Dynamic Nav) abzurufen. Zuerst erhalte ich die Liste . dann versuche ich die Daten daraus zu extrahieren. –

+0

Ist die Datenbank auf einem SQL Server? In diesem Fall können Sie die Dynamic Nav-Schnittstelle und zusätzliche Daten direkt vom Server umgehen. – jdweng

+0

Die Daten sind in Dynamic Nav. Wir greifen über OData Service darauf zu. Zu der Liste bekomme ich alle Daten, die ich filtern muss. –

Verwandte Themen