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