C# 如何展平嵌套对象(LINQ)
我正在一个旧的Winforms网格上做一些工作,我有两个模型,我正试图将它们展平并分配给DataGridView 这是我的样品模型C# 如何展平嵌套对象(LINQ),c#,linq,datagridview,models,C#,Linq,Datagridview,Models,我正在一个旧的Winforms网格上做一些工作,我有两个模型,我正试图将它们展平并分配给DataGridView 这是我的样品模型 public class StockItem { public string StockName { get; set; } public int Id { get; set; } public List<Warehouse> Warehouses { get; set; } } public class Warehous
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; }
}
我试图通过Linq查询来实现这一点,但只能获得每个StockItem\Warehouse的记录。我不建议这样做,但您可以使用对象创建具有所需形状的对象这样做不是常见的C#模式。这在Python或Javascript等语言中更常见
C#是一种强类型语言,只有在绝对必要时才应该考虑冒险进入动态对象的世界(想想解析json blob)。我强烈认为你重新评估你需要做的事情,并从不同的角度去看待它。 < P>这应该给你所需要的:
var flattened = stockItems
.Select(x => new {
StockName = x.StockName,
WarehouseNames = x.Warehouses
.Select(y => y.WarehouseName)
.ToList() })
.ToList();
它将生成包含StockName
的项目集合和WarehouseName
字符串列表<添加代码>列表以枚举查询
对于这些样本数据:
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" }
}
}
};
List stockItems=新列表
{
新库存项目
{
StockName=“A”,
Id=1,
仓库=新列表
{
新仓库{Id=1,WarehouseName=“x”},
新仓库{Id=2,WarehouseName=“y”}
}
},
新库存项目
{
StockName=“B”,
Id=2,
仓库=新列表
{
新仓库{Id=3,WarehouseName=“z”},
新仓库{Id=4,WarehouseName=“w”}
}
}
};
我得到了以下结果:
类似这样的内容:
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);
}
var availablewalehouses=new[]{
新仓库{
WarehouseName=“Warehouse1”,
Id=1
},
新仓库{
WarehouseName=“Warehouse2”,
Id=2
},
新仓库{
WarehouseName=“Warehouse3”,
Id=3
}
};
var股票=新[]{
新库存项目{
StockName=“StockCode1”,
Id=1,
仓库=新列表{availableWarehouses[0],availableWarehouses[1],availableWarehouses[2]}
},
新库存项目{
StockName=“StockCode2”,
Id=2,
仓库=新列表{availableWarehouses[0],availableWarehouses[1]}
},
新库存项目{
StockName=“StockCode3”,
Id=3,
仓库=新列表{availableWarehouses[0],availableWarehouses[2]}
}
};
var Flant=股票。选择(项目=>新建{
StockName=item.StockName,
WarehousesNames=availableWarehouses.Select(仓库=>item.Warehouses.Contains(仓库)?warehouse.WarehouseName:)
.Aggregate((当前,下一个)=>当前+“\t”+下一个)
});
foreach(展平中的var项目){
Console.WriteLine(“{0}\t{1}”,item.StockName,item.WarehousesNames);
}
您可以通过创建一个数据表来实现它,您可以轻松地将其用作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);
}
也许这会有帮助?这不是真正的扁平化,而是交叉表/数据透视结果数据类型是什么?是否存在可与库存项目关联的最大可能仓库数
?我不熟悉WinFormsDataGridView
,因此我可能缺少一些东西,但您不需要将其绑定到强类型对象集合吗?对于数量可变的仓库,您似乎无法做到这一点。您能否创建一段代码并共享您构建数据的方式?但一般来说,您应该能够使用LINQ查询获得数据。
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);
}