grouping with linq
class Customer
{
public string ID { get; set; }
public string Name { get; set; }
public List<Order> OrderList { get; set; }
}
class Order
{
public string OrderNumber { get; set; }
public List<Item> ItemList { get; set; }
}
class Item
{
public string ItemName { get; set; }
}
static void Main(string[] args)
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("CustID");
dt.Columns.Add("Name");
dt.Columns.Add("OrderNumber");
dt.Columns.Add("ItemName");
dt.Rows.Add("1", "A", "O1", "Item1");
dt.Rows.Add("1", "A", "O1", "Item2");
dt.Rows.Add("1", "A", "O1", "Item3");
dt.Rows.Add("1", "A", "O2", "Item4");
dt.Rows.Add("1", "A", "O2", "Item5");
dt.Rows.Add("1", "A", "O3", "Item1");
dt.Rows.Add("2", "B", "O4", "Item1");
开发者_高级运维dt.Rows.Add("2", "B", "O4", "Item2");
dt.Rows.Add("2", "B", "O5", "Item3");
dt.AcceptChanges();
List<DataRow> dList = dt.AsEnumerable().ToList();
//This is not working
var qry = dList.GroupBy(x => x["CustID"])
.Select(g => new Customer
{
ID = g.Key.ToString(),
Name = g.First()["Name"].ToString(),
OrderList = g.GroupBy(t=> t["OrderNumber"]).Select(x => new Order
{
OrderNumber = x.First()["OrderNumber"].ToString(),
ItemList = g.GroupBy(u => u["OrderNumber"]).Select(y => new Item { ItemName = y.First()["ItemName"].ToString() }).ToList()
}).ToList()
}).ToList();
}
I am trying to get output like this
Custtomer.Name="A"
Customer.ID="1"
Customer.OrderList = ListOfOrders with "01", "02", "03"
Customer.OrderList[0].ItemList = ListOfItems with that order Item1, Item2, Item3
Custtomer.Name="B"
Customer.ID="2"
Customer.OrderList = ListOfOrders with "04", "05"
Customer.OrderList[0].ItemList = ListOfItems with that order Item4, Item5
Can someone tell me whats wrong with my qry?
Yes, you're trying to use x
within the Select
call, but it's out of scope. Also, you're trying to use the Name
directly, but it's not part of the grouping key. Finally, you're trying to select a single order in your Select, not a group of them. I think you want this:
var qry = dList.GroupBy(x => new { CustID = (string) x["CustID"],
Name = (string) x["Name"] })
.Select(g => new Customer {
ID = g.Key.CustID,
Name = g.Key.Name,
OrderList = g.Select(x => new Order {
// Indentation bad to avoid scrolling!
OrderNumber = (string) x["OrderNumber"] })
.ToList()
})
.ToList();
Assuming that CustID is unique (so you'll get the same Name each time) you can group just by CustID and then take the first customer for the Name, as per Achim's answer - but personally I prefer to group all the "per customer" data in the key, as that's logically what you're grouping on.
EDIT: To answer the edited question, you could populate the OrderList
property something like this:
OrderList = g.GroupBy(t=> (string) t["OrderNumber"]).Select(x => new Order
{
OrderNumber = x.Key,
ItemList = x.Select(y => new Item {
ItemName = (string) y["ItemName"]
}).ToList()
}).ToList()
... but to be honest it's getting pretty messy by then.
var qry = dList.GroupBy(x => x["CustID"]).Select(g => new Customer
{
ID = g.Key.ToString(),
Name = g.First()["Name"],
OrderList=g.Select(o => new List<Order>(new Order{ OrderNumber=o["OrderNumber"]}))
}).ToList();
精彩评论