简体   繁体   中英

LINQ - Groupy by for complex xml

I have following XML:-

<customer>
    <id>ALFKI</id>
    <name>Alfreds Futterkiste</name>
    <address>Obere Str. 57</address>
    <city>Berlin</city>
    <postalcode>12209</postalcode>
    <country>Germany</country>
    <phone>030-0074321</phone>
    <fax>030-0076545</fax>
    <orders>
      <order>
        <id>10643</id>
        <orderdate>1997-08-25T00:00:00</orderdate>
        <total>814.50</total>
      </order>
      <order>
        <id>10692</id>
        <orderdate>1997-10-03T00:00:00</orderdate>
        <total>878.00</total>
      </order>
    </orders>
</customer>

I want to fetch data in following format:- Country Name: Germany City Name : Berlin orders: orderid1, orderid2...

City Name: Mannheim orders: orderid1, orderid2 etc..

ie for each country, its respective cities and for that city all the orderids.

I am using the below query by which i am able to group country and its cities but i am not able to fetch the orders for that country:-

List<Customer> Customers = GetCustomerData();
            var query = (from cust in Customers
                         from ord in cust.Orders 
                         group cust by cust.Country into CountryGroup
                         select new
                         {
                             CountryName = CountryGroup.Key,
                             CityGroup = (from c in CountryGroup 
                                          where c.Country == CountryGroup.Key 
                                          group c by c.City into CityGroup
                                          select new
                                          {
                                              CityName = CityGroup.Key
                                          })

                         });

Code for GetCustomerData:-

CustomerList = (from e in XDocument.Load(@"D:\Console Application\LINQDemo\GroupingOperators\GroupingOperators\XMLFiles\Customers.xml").Root.Elements("customer")
                            select new Customer
                            {
                                CustomerID = (string)e.Element("id"),
                                CustomerName = (string)e.Element("name"),
                                Address = (string)e.Element("address"),
                                City = (string)e.Element("city"),
                                Region = (string)e.Element("region"),
                                PostalCode = (string)e.Element("postalcode"),
                                Country = (string)e.Element("country"),
                                PhoneNo = (string)e.Element("phone"),
                                Fax = (string)e.Element("fax"),
                                Orders = (from o in e.Element("orders").Elements("order")
                                          select new Order
                                          {
                                              OrderID = (int)o.Element("id"),
                                              OrderDate = (DateTime)o.Element("orderdate"),
                                              OrderTotal = (decimal)o.Element("total")
                                          }).ToArray()
                            }).ToList();

Please Help!

TIA.

If you do correct parsing of customers, then your query should look like:

var query = from cust in Customers
            group cust by new { cust.Country, cust.City } into g
            select new
            {
                CountryName = g.Key.Country,
                CityGroup = g.Key.City,
                Orders = g.SelectMany(c => c.Orders)
            };

And here is parsing (just in case):

private List<Customer> GetCustomerData()
{            
    XDocument xdoc = XDocument.Load(path_to_xml);
    return xdoc.Descendants("customer")
                .Select(c => new Customer()
                {
                    Id = (string)c.Element("id"),
                    Name = (string)c.Element("name"),
                    Address = (string)c.Element("address"),
                    Country = (string)c.Element("country"),
                    City = (string)c.Element("city"),
                    Orders = c.Descendants("order")
                                .Select(o => new Order()
                                {
                                    Id = (int)o.Element("id"),
                                    Date = (DateTime)o.Element("orderdate"),
                                    Total = (decimal)o.Element("total")
                                }).ToList()
                }).ToList();
}

Where I used following classes (without postal code, fax and phone)

public class Customer
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Country { get; set; }
    public string City { get; set; }
    public List<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public decimal Total { get; set; }
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM