2016-09-13 3 views
2

Я работаю над старой сеткой Winforms, и у меня есть две Модели, которые я пытаюсь сгладить и назначить DataGridView.Как сгладить вложенные объекты (LINQ)

Вот мои образцы моделей.

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

Данные работает таким образом, что склад должен сначала быть создан, а затем присваивается каждому StockItem. A StockItem может иметь все склады или может иметь только один.

Мне нужно сгладить данные, чтобы сетка отображала StockName, а затем все связанные с ними склады для элемента запаса.

Пример

StockCode1  Warehouse1 Warehouse2 Warehouse3 
StockCode2  Warehouse1 Warehouse2 
StockCode2  Warehouse1    Warehouse3 

Я попытался сделать это с помощью запроса Linq, но может получить только запись на StockItem \ Warehouse.

+0

Возможно, это поможет? http://stackoverflow.com/questions/6428940/how-to-flatten-nested-objects-with-linq-expression –

+2

На самом деле это не сглаживание, а кросс-таблица/поворот –

+1

. Каким будет результирующий тип данных? Существует ли максимальное количество возможных складов, которые могут быть связаны с «StockItem»? Я не знаком с WinForms 'DataGridView', поэтому может быть что-то, что мне не хватает, но не нужно было привязывать его к набору строго типизированных объектов?Похоже, что с переменным количеством складов вы не могли этого сделать. –

ответ

1

Вы можете достичь этого путем создания a DataTable, что yon можно легко использовать в качестве источника e для gridview. Сначала добавьте все столбцы, а затем для каждой акции добавить склады:

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

я не рекомендовать его, но вы можете использовать dynamic объекты для создания объектов с формой вы хотите. Выполнение этого не является распространенным шаблоном C#. Это чаще встречается в таких языках, как Python или Javascript.

C# - это строго типизированный язык и вступающий в мир динамических объектов должен быть рассмотрен только в (подумайте, разобрав json blob). Я решительно считаю, что вы переоцениваете то, что вам нужно делать, и подходите к нему под другим углом.

-1

Это должно дать вам то, что вам нужно:

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

Это приведет к коллекции элементов, содержащих StockName и список WarehouseName строк. ToList добавлено для перечисления запроса.

Для этих образцов данных:

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

я получил следующий результат:

enter image description here

0

Что-то вроде этого:

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); 
} 
Смежные вопросы