재우니의 블로그

customers, orders 의 datatable 을 만들고, key 는 CustomerID 로 하였음. 이를 relation 함수를 사용하여 CustomerID 에 대한 관계설정을 함. 1:다 관계를 유지함. (cstomers :1, orders : 다)


DataTable customers = new DataTable("Customers");
            customers.Columns.Add("CustomerID", typeof(string));
            customers.Columns.Add("CompanyName", typeof(string));
            customers.Columns.Add("Address", typeof(string));
            customers.Columns.Add("City", typeof(string));
            customers.Columns.Add("Region", typeof(string));
            customers.Columns.Add("PostalCode", typeof(string));
            customers.Columns.Add("Country", typeof(string));
            customers.Columns.Add("Phone", typeof(string));
            customers.Columns.Add("Fax", typeof(string));

            ds.Tables.Add(customers);



            DataTable orders = new DataTable("Orders");

            orders.Columns.Add("OrderID", typeof(int));
            orders.Columns.Add("CustomerID", typeof(string));
            orders.Columns.Add("OrderDate", typeof(DateTime));
            orders.Columns.Add("Total", typeof(decimal));

            ds.Tables.Add(orders);



            DataRelation co = new DataRelation("CustomersOrders", customers.Columns["CustomerID"], orders.Columns["CustomerID"], true);
            ds.Relations.Add(co);
그 다음, customers.xml 파일이 래와 같이 xml 형태로 되어 있다.

<?xml version="1.0"?>
<CUSTOMERS>
    <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>
            <ORDER>
                <ID>10702</ID>
                <ORDERDATE>1997-10-13T00:00:00</ORDERDATE>
                <TOTAL>330.00</TOTAL>
            </ORDER>
        </ORDERS>
    </CUSTOMER>
    <CUSTOMER>
        <ID>ANATR</ID>
        <NAME>Ana Trujillo Emparedados y helados</NAME>
        <ADDRESS>Avda. de la Constitución 2222</ADDRESS>
        <CITY>México D.F.</CITY>
        <POSTALCODE>05021</POSTALCODE>
        <COUNTRY>Mexico</COUNTRY>
        <PHONE>(5) 555-4729</PHONE>
        <FAX>(5) 555-3745</FAX>
        <ORDERS>
            <ORDER>
                <ID>10308</ID>
                <ORDERDATE>1996-09-18T00:00:00</ORDERDATE>
                <TOTAL>88.80</TOTAL>
            </ORDER>
            <ORDER>
                <ID>10625</ID>
                <ORDERDATE>1997-08-08T00:00:00</ORDERDATE>
                <TOTAL>479.75</TOTAL>
            </ORDER>
        </ORDERS>
    </CUSTOMER>
</CUSTOMERS>
 
이 xml 을 두개의 relation 된 dataset 에 할당할 것이다. xml 을 읽기 위해서는 linq 의 xdocument 함수를 사용해야 한다.

var customerList = (
                from e in XDocument.Load("customers.xml").
                          Root.Elements("customer")
                select new Customer
                {
                    CustomerID = (string)e.Element("id"),
                    CompanyName = (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"),
                    Phone = (string)e.Element("phone"),
                    Fax = (string)e.Element("fax"),
                    Orders = (
                        from o in e.Elements("orders").Elements("order")
                        select new Order
                        {
                            OrderID = (int)o.Element("id"),
                            OrderDate = (DateTime)o.Element("orderdate"),
                            Total = (decimal)o.Element("total")
                        })
                        .ToArray()
                }
                ).ToList();



            foreach (Customer cust in customerList)
            {
                customers.Rows.Add(new object[] {cust.CustomerID, cust.CompanyName, cust.Address, cust.City, cust.Region,  cust.PostalCode, cust.Country, cust.Phone, cust.Fax});


                foreach (Order order in cust.Orders)
                {
                    //join 할 키값인 cust.CustomerID 키값을 할당한다.
                    orders.Rows.Add(new object[] { order.OrderID, cust.CustomerID, order.OrderDate, order.Total });


                }
            }


이제 xml 에서 받은 데이터를 dataset 에 할당 받고, 이를 groupby 를 통해 회사별로 그룹핑 한 다음, 이를 다시 년도로 구분하고, 다시 월로 구분하여 트리형태로 보여주는 방법으로 linq 를 구현한 코드이다. linq 를 구현하기 위해서는 뭐든 AsEnumerable() 함수를 호출해서 enumerable 하게 해야 한다. linq 코드는 간결하면서도 코드가 몇줄 안된다. 정말 예술같은 코드이기도 하다.


var customers = testDS.Tables["Customers"].AsEnumerable();



                var customerOrderGroups =
                    from c in customers
                    select
                        new
                        {
                            CompanyName = c.Field("CompanyName"),
                            YearGroups =
                                from o in c.GetChildRows("CustomersOrders")
                                group o by o.Field("OrderDate").Year into yg
                                select
                                    new
                                    {
                                        Year = yg.Key,
                                        MonthGroups =
                                            from o in yg
                                            group o by o.Field("OrderDate").Month into mg
                                            select new { Month = mg.Key, Orders = mg }
                                    }
                        };

                foreach (var cog in customerOrderGroups)
                {
                    Console.WriteLine("CompanyName= {0}", cog.CompanyName);
                    foreach (var yg in cog.YearGroups)
                    {
                        Console.WriteLine("\t Year= {0}", yg.Year);
                        foreach (var mg in yg.MonthGroups)
                        {
                            Console.WriteLine("\t\t Month= {0}", mg.Month);
                            foreach (var order in mg.Orders)
                            {
                                Console.WriteLine("\t\t\t OrderID= {0} ", order.Field("OrderID"));
                                Console.WriteLine("\t\t\t OrderDate= {0} ", order.Field("OrderDate"));
                            }
                        }
                    }
                }