2016-09-13 2 views
2

Ich arbeite an einem alten WinForms-Grid und habe zwei Modelle, die ich verflachen und einem DataGridView zuweisen möchte.Wie verschachtelte Objekte (LINQ) geglättet werden

Hier sind meine Beispielmodelle.

public class StockItem 
{ 
    public string StockName { get; set; } 
    public int Id { get; set; } 
    public List<Warehouse> Warehouses { get; set; } 
} 

public class Warehouse 
{ 
    public string WarehouseName { get; set; } 
    public int Id { get; set; } 
} 

Die Daten arbeitet in einer Weise, dass ein Lager muss zuerst und jedem StockItem dann zugewiesen erstellt werden. A StockItem kann alle Lager haben oder nur eines haben.

Ich muss die Daten abflachen, so dass das Raster zeigt die StockName und dann alle zugehörigen Lager für den Lagerartikel.

Beispiel

StockCode1  Warehouse1 Warehouse2 Warehouse3 
StockCode2  Warehouse1 Warehouse2 
StockCode2  Warehouse1    Warehouse3 

Ich habe versucht, dies über eine Linq-Abfrage zu tun, sondern nur einen Datensatz pro Lager lieferbar \ Warehouse erhalten.

+0

Vielleicht hilft dies? http://stackoverflow.com/questions/6428940/how-to-flatten-nested-objects-with-linq-expression –

+2

Dies ist nicht wirklich flach, aber Kreuztabellen/Pivoting –

+1

Was wäre der resultierende Datentyp? Gibt es eine maximale Anzahl von möglichen Lagern, die einem StockItem zugeordnet werden können? Ich bin nicht mit dem WinForms 'DataGridView' vertraut, so dass ich etwas vermisse, aber nicht müssen Sie es an eine Sammlung von stark typisierten Objekten binden?Es scheint, dass dies bei einer variablen Anzahl von Lagern nicht möglich ist. –

Antwort

1

Sie können es erreichen, indem a DataTable, die Sie leicht als Quelle verwenden können f oder die Gridview. Zuerst alle Spalten hinzufügen und dann für jede Aktie fügen Sie die Lager:

var warehouseNames = 
    stocks 
    .SelectMany(x => x.Warehouses.Select(y => y.WarehouseName)).Distinct(); 

var dt = new DataTable(); 
dt.Columns.Add("StockCode"); 

foreach (var name in warehouseNames) 
{ 
    dt.Columns.Add(name); 
} 

foreach (var stock in stocks) 
{ 
    var row = dt.NewRow(); 
    row["StockCode"] = stock.Id; 
    foreach (var warehouse in stock.Warehouses) 
    { 
     row[warehouse.WarehouseName] = warehouse.Id; 
    } 
    dt.Rows.Add(row); 
} 

Warehouses

0

ich nicht es empfehlen, aber Sie können dynamic Objekte verwenden, um Objekte zu erstellen mit der Form, die Sie wollen. Dies ist kein übliches C# -Muster. Dies ist häufiger in Sprachen wie Python oder Javascript.

C# ist eine stark typisierte Sprache und wagt sich in die Welt dynamischer Objekte, sollte nur in Betracht gezogen werden, wenn absolut notwendig (denke, ein JSON-Blob zu analysieren). Ich halte es für sehr wichtig, dass Sie das, was Sie tun müssen, neu bewerten und es aus einem anderen Blickwinkel betrachten.

-1

Das sollten Sie geben, was Sie brauchen:

var flattened = stockItems 
    .Select(x => new { 
       StockName = x.StockName, 
       WarehouseNames = x.Warehouses 
            .Select(y => y.WarehouseName) 
            .ToList() }) 
    .ToList(); 

Es ist in einer Sammlung von Gegenständen führen, die StockName und eine Liste der WarehouseName Strings enthalten. ToList hinzugefügt, um die Abfrage aufzulisten.

Für diese Beispieldaten:

List<StockItem> stockItems = new List<StockItem> 
{ 
    new StockItem 
    { 
     StockName ="A", 
     Id = 1, 
     Warehouses = new List<Warehouse> 
     { 
      new Warehouse { Id = 1, WarehouseName = "x" }, 
      new Warehouse { Id = 2, WarehouseName = "y" } 
     } 
    }, 
    new StockItem 
    { 
     StockName = "B", 
     Id = 2, 
     Warehouses = new List<Warehouse> 
     { 
      new Warehouse { Id = 3, WarehouseName = "z" }, 
      new Warehouse { Id = 4, WarehouseName = "w" } 
     } 
    } 
}; 

ich folgendes Ergebnis haben:

enter image description here

0

Etwas wie folgt aus:

var availableWarehouses = new [] { 
    new Warehouse { 
     WarehouseName = "Warehouse1", 
     Id = 1 
    }, 
    new Warehouse { 
     WarehouseName = "Warehouse2", 
     Id = 2 
    }, 
    new Warehouse { 
     WarehouseName = "Warehouse3", 
     Id = 3 
    } 
}; 

var stocks = new [] { 
    new StockItem { 
     StockName = "StockCode1", 
     Id = 1, 
     Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[1], availableWarehouses[2] } 
    }, 
    new StockItem { 
     StockName = "StockCode2", 
     Id = 2, 
     Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[1] } 
    }, 
    new StockItem { 
     StockName = "StockCode3", 
     Id = 3, 
     Warehouses = new List<Warehouse> { availableWarehouses[0], availableWarehouses[2] } 
    } 
}; 

var flatten = stocks.Select(item => new { 
     StockName = item.StockName, 
     WarehousesNames = availableWarehouses.Select(warehouse => item.Warehouses.Contains(warehouse) ? warehouse.WarehouseName : "   ") 
      .Aggregate((current, next) => current + "\t" + next) 
    }); 

foreach(var item in flatten) { 
    Console.WriteLine("{0}\t{1}", item.StockName, item.WarehousesNames); 
} 
Verwandte Themen