잊지 않겠습니다.

Pro LINQ (04)

Book 2009. 1. 9. 01:02
XML을 얻는다면 일반적으로 XmlDocument를 선언하고, XmlDocument에서 지정된 Node의 선택과 node에 대한 Tree 구조로 탐색을 하게 된다. 그러나, LINQ를 사용하게 될 경우에는 이러한 Tree 구조 탐색에 별 의미가 없게 된다. 

XElement에서 각 이름에 대한 검색 및 각 속성에 대한 검색을 모두 지원하고 있다. 다음 소스의 결과는 다음과 같다. 

        public void DoForAncestors()
        {

            XDocument xDocument = new XDocument(
                new XElement("BookParticipants",
                             new XElement("BookParticipant",
                                          new XAttribute("type", "Author"),
                                          new XElement("FirstName", "Joe"),
                                          new XElement("LastName", "Rattz")),
                             new XElement("BookParticipant",
                                          new XAttribute("type", "Editor"),
                                          new XElement("FirstName", "Ewan"),
                                          new XElement("LastName", "Buckingham"))));
            Console.WriteLine("Original XML : ");
            Console.WriteLine(xDocument.ToString());
            Console.WriteLine();
            Console.WriteLine("Search node : name == FirstName");
            var elements = xDocument.Element("BookParticipants").Descendants("FirstName");
            foreach(var element in elements)
            {
                Console.WriteLine(element.Value);
            }
        }



기존의 경우에는 모든 node의 트리 구조를 알고 있어서 xpath를 이용해서 SelectSingleNode 또는 SelectNodeList를 이용해서 각 값을 구해주었지만, LINQ를 이용하면, node에 대한 이름만을 이용해서 얻는 것이 가능하다. 그리고 얻어진 node에서 각 Parent를 얻어내는 것도 가능하다. 

여기에서 한가지 의문이 생기는 것이... 기존의 XmlDocument의 경우에는 거의 필요가 없는 class가 되어버리는 경향이 있는 것 같다. XmlDocument에서 이용하던 거의 모든 method들을 XDocument에서 제공하고 있으며, LINQ 및 보다더 선언적인 XML을 선언할 수 있는 것까지. 지금은 잘 모르겠지만.. 아무래도 XmlDocument를 앞으로는 사용할 일이 그다지 없지 않을까 라는 성급한 생각도 해보게 된다. (물론 .NET Framework 2.0에서의 경우는 또 다르다.;)

XML을 검색을 할때에 Element, Processing, Comment에 대한 검색을 하는 것 역시 LINQ에서 지원이 가능하다. 
또한 선언적인 Type을 넣어줄 수 있기 때문에 코드의 가독성 역시 같이 높아진다. 

        public void SearchForType()
        {
            XDocument xDocument = new XDocument(
                        new XElement("BookParticipants",
                         new XElement("BookParticipant",
                                      new XAttribute("type", "Author"),
                                      new XComment("This is XComment"),
                                      new XProcessingInstruction("Processing", "New Processing"),
                                      new XElement("FirstName", "Joe"),
                                      new XElement("LastName", "Rattz")),
                         new XElement("BookParticipant",
                                      new XAttribute("type", "Editor"),
                                      new XElement("FirstName", "Ewan"),
                                      new XElement("LastName", "Buckingham"))));
            Console.WriteLine(xDocument.ToString());
            Console.WriteLine();

            var elements = xDocument.Element("BookParticipants").
                Elements("BookParticipant").Nodes().OfType<XComment>();

            foreach(var element in elements)
            {
                Console.WriteLine(element);
            }
        }



Posted by Y2K
,
XElement를 이용하면 XmlDocument를 이용한 XmlDocument의 생성보다 편하고 직관적인 방법을 제공할 수 있다.

XElement - Element 생성
XComment - Comments 생성
XDeclaration - Declaration 생성

    public class XmlLinq2
    {
        public void CreateXmlDocument()
        {
            XNamespace nameSpace = "http://www.hostway.co.kr";
            XElement xBookParticipant = new XElement(nameSpace + "BookParticipant");
            XAttribute bookAttribute = new XAttribute("type", "Author");
            XElement xFirstname = new XElement(nameSpace + "FirstName", "Joe");
            XElement xLastName = new XElement(nameSpace + "LastName", "Rattz");
            XComment xComment = new XComment("This is XComment");

            xBookParticipant.Add(bookAttribute);
            xBookParticipant.Add(xComment);
            xBookParticipant.Add(xFirstname);
            xBookParticipant.Add(xLastName);

            Console.WriteLine(xBookParticipant);
        }

        public void FindDatas()
        {
            XNamespace nameSpace = "http://www.hostway.co.kr";
            XElement xBookParticipant = new XElement(nameSpace + "BookParticipant", 
                                                     new XElement(nameSpace + "FirstName", "Joe"),
                                                     new XElement(nameSpace + "LastName", "Rattz"));
            Console.WriteLine(xBookParticipant.ToString());
            Console.WriteLine(xBookParticipant);
        }
    }

: 기초책을 볼때마다 느끼는 거지만.. 언제나 기본인 내용을 모르고 있는 내 모습이 많이 부끄러워질때가 많은 것 같다. 


Posted by Y2K
,

Pro LINQ (03)

Book 2009. 1. 8. 00:28
먼저 설명된 select, take 등이 지연된 operation이라면, 모든 Action이 호출즉시 나오게 된다. 이럴 경우에는 LINQ가 가진 속도의 장점을 잃어버리게 된다. 그렇지만 모든 객체를 한번에 얻어와서 일을 처리하게 될 경우에는 보다더 용의하게 된다. 

    public class DataContextLinq
    {
        public void QueryDatas()
        {
            NorthwindDataContext dbContext = new NorthwindDataContext(@"Data Source=Y2K\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True");
            dbContext.Log = Console.Out;

            Console.WriteLine("Queried datas - Start");
            var products = (from p in dbContext.Products where p.Color == "Red" select p.Name).ToList();
            Console.WriteLine("Queried datas - End");
            
            Console.WriteLine("Deferred Operation - Start");
            foreach(string productName in products)
            {
                Console.WriteLine(productName);
            }
        }
    }

결과는 다음과 같다. 

차이를 보면, 값을 얻어오는 순간 모든 Query가 실행이 되고, 전 값을 다 얻어오게 된다. 
nondeferred operation은 다음과 같다. 

ToArray()
ToList()
ToDictionary()
ToLookup()
First()
FirstOrDefault()
LastOrDefault()
Single()
SingleOrDefault()
ElementAt()
Sum()
Max()
Min()
etc.... 


경우에 따라 deferred operation과 non-deferred operation의 사용을 달리해줄 필요가 있다. 많은 양의 데이터를 가지고 온다면 deferred operation이 속도 면에서 더 나은 선택이 되지만, 많은 데이터에 대해서 일괄처리를 하게 될 경우에는 non-deferred operation이 선택이 될 수 있다. 











Posted by Y2K
,