<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dmitry&#039;s Blog</title>
	<atom:link href="http://dmitrykiev.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dmitrykiev.wordpress.com</link>
	<description></description>
	<lastBuildDate>Wed, 21 Apr 2010 21:36:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dmitrykiev.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Dmitry&#039;s Blog</title>
		<link>http://dmitrykiev.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dmitrykiev.wordpress.com/osd.xml" title="Dmitry&#039;s Blog" />
	<atom:link rel='hub' href='http://dmitrykiev.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Orders Viewer</title>
		<link>http://dmitrykiev.wordpress.com/2009/10/20/orders-viewer/</link>
		<comments>http://dmitrykiev.wordpress.com/2009/10/20/orders-viewer/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 07:47:37 +0000</pubDate>
		<dc:creator>dmitrykiev</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://dmitrykiev.wordpress.com/?p=43</guid>
		<description><![CDATA[Description. Create a program to view orders: Create a database with the tables &#8216;Order&#8217;, &#8216;Product&#8217;, &#8216;Amount&#8217;; Provide scripts to create the database and populate it with test data; Access database using the NHibernate 2; Get data on the client using the WCF service; Display data in the Infragistics UltraGrid; Display order details in a separate [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dmitrykiev.wordpress.com&amp;blog=8616169&amp;post=43&amp;subd=dmitrykiev&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Description.</h3>
<p><span style="font-weight:normal;font-size:13px;">Create a program to view orders:</span></p>
<ul>
<li> Create a database with the tables &#8216;Order&#8217;, &#8216;Product&#8217;, &#8216;Amount&#8217;;</li>
<li>Provide scripts to create the database and populate it with test data;</li>
<li>Access database using the NHibernate 2;</li>
<li>Get data on the client using the WCF service;</li>
<li>Display data in the Infragistics UltraGrid;</li>
<li>Display order details in a separate grid;</li>
<li>User should be able to select some items in the details grid and display them as an xml document in the text field;</li>
<li>User should be able to edit the xml document and send it to the server where it is being validated;</li>
<li>If validation is passed the service returns the positions as a list and client displays it in a separate window.</li>
</ul>
<p>I have created a simple ADO.NET project to populate the database with the test data which can be found in the downloadable source code. Sql Server allows to publish the database schema as a script but to publish the database along with the data some helper tool should be used, for example, <a href="http://www.microsoft.com/downloadS/details.aspx?familyid=56E5B1C5-BF17-42E0-A410-371A838E570A&amp;displaylang=en">Microsoft SQL Server Database Publishing Wizard</a>. It allows to publish the database schema and data, schema only or data only.</p>
<p>NHibernate project can be created using <a href="http://www.codesmithtools.com/features/frameworks.aspx">CodeSmith Tools</a>. Next add the method to return orders for the specified period:</p>
<pre class="brush: csharp;">
        public IList&lt;MyOrder&gt; GetOrders(DateTime from, DateTime to)
        {
            IList&lt;MyOrder&gt; orders;
            using (ISession session = NHibernateHelper.OpenSession())
            {
                orders = session.CreateQuery(&quot;from Order where date between :from and :to&quot;)
                    .SetParameter(&quot;from&quot;, from)
                    .SetParameter(&quot;to&quot;, to.AddDays(1))
                    .List&lt;MyOrder&gt;();

                foreach (var order in orders)
                {
                    NHibernateUtil.Initialize(order.Amounts);
                    foreach (var amount in order.Amounts)
                    {
                        NHibernateUtil.Initialize(amount.Product);
                    }
                }
            }
            return orders;
        }
</pre>
<p>&#8220;from Order where date between :from and :to&#8221; is the Hibernate Query Language statement, &#8220;:from&#8221; and &#8220;:to&#8221; are parameters, their values are set in the SetParameter() method. The call to List&lt;MyOrder&gt;() method forces the query to evaluate immediately. NHibernateUtil.Initialize() method loads linked data.</p>
<p>Next create the WCF service and add a method to get orders:</p>
<pre class="brush: csharp;">
        public IList&lt;Order&gt; GetOrders(DateTime from, DateTime to)
        {
            OrderRepository repository = new OrderRepository();
            return repository.GetOrders(from, to);
        }
</pre>
<p>On the client add the service reference, call the service and display the results:</p>
<pre class="brush: csharp;">
        private void showOrdersButton_Click(object sender, EventArgs e)
        {
            Order[] orders;
            try
            {
                orders = serviceClient.GetOrders(dateFrom.Value.Date, dateTo.Value.Date);
            }
            catch (Exception)
            {
                MessageBox.Show(&quot;Service Error.&quot;);
                return;
            }

            ordersGrid.DataSource = orders;
        }
</pre>
<p>UltraGrid customization is performed in the InitializeLayout event handler:</p>
<pre class="brush: csharp;">
        private void ordersGrid_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
        {
            //Set columns' order and visibility.
            ordersGrid.DisplayLayout.Bands[0].Columns[0].Hidden = true;
            ordersGrid.DisplayLayout.Bands[0].Columns[3].Hidden = true;
            ordersGrid.DisplayLayout.Bands[0].Columns[4].Header.VisiblePosition = 0;
            ordersGrid.DisplayLayout.Bands[0].Columns[2].Header.VisiblePosition = 1;

            //Select entire row on click and make all columns to be the same size.
            ordersGrid.DisplayLayout.Override.CellClickAction = CellClickAction.RowSelect;
            ordersGrid.DisplayLayout.AutoFitStyle = AutoFitStyle.ResizeAllColumns;
        }
</pre>
<p>CreateXMLStringFromSelectedRows() creates xml document from the selected items in the details grid:</p>
<pre class="brush: csharp;">
        private static string CreateXMLStringFromSelectedRows(SelectedRowsCollection selectedRows)
        {
            TextWriter stringWriter = new StringWriter();
            XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
            xmlWriter.Formatting = Formatting.Indented;

            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement(&quot;Positions&quot;);

            foreach (var row in selectedRows)
            {
                xmlWriter.WriteStartElement(&quot;Position&quot;);

                xmlWriter.WriteStartElement(&quot;Product&quot;);
                xmlWriter.WriteString(((OrderDetails)row.ListObject).Product);
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement(&quot;Amount&quot;);
                xmlWriter.WriteString(((OrderDetails)row.ListObject).Amount.ToString());
                xmlWriter.WriteEndElement();

                xmlWriter.WriteEndElement();
            }

            xmlWriter.WriteEndElement();

            xmlWriter.Flush();
            xmlWriter.Close();
            stringWriter.Flush();

            return stringWriter.ToString();
        }
</pre>
<p>This approach has some issues for encoding since .NET uses UTF-16 encoding for strings.  You can follow this <a href="http://weblogs.asp.net/rmclaws/archive/2003/07/31/22080.aspx">post</a> and comments for more information.</p>
<p>Now add a method to the service to parse the xml string and return the list of items:</p>
<pre class="brush: csharp;">
        private List&lt;string&gt; validationErrors = new List&lt;string&gt;();

        public IList&lt;string&gt; GetOrderDetailsFromXML(string xmlString)
        {
            IList&lt;string&gt; result = new List&lt;string&gt;();
            string errorMessage = String.Empty;
            validationErrors = new List&lt;string&gt;();
            XmlDocument doc = new XmlDocument();
            XmlReader docReader = CreateXmlReader(ref xmlString);
            ...
        }
</pre>
<p>CreateXmlReader() method creates an object of the XmlReaderSettings class, specifies the xsd schema to validate against and registers ValidationEventHandler:</p>
<pre class="brush: csharp;">
        private XmlReader CreateXmlReader(ref string xmlString)
        {
            //If encoding of the xml document is specified &quot;encoding=&quot;utf-16&quot;&quot;,
            //replace it with &quot;encoding=&quot;utf-8&quot;&quot;.
            xmlString = Regex.Replace(xmlString, &quot;encoding=.utf-16.&quot;, &quot;encoding=\&quot;utf-8\&quot;&quot;);

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;

            //Load schema in shemas collection.
            TextReader stringReader = new StringReader(Properties.Resources.schema);
            XmlReader schemaDocument = new XmlTextReader(stringReader);
            settings.Schemas.Add(&quot;&quot;, schemaDocument);

            settings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(OnValidationError);
            XmlReader docReader = XmlReader.Create(new StringReader(xmlString), settings);

            return docReader;
        }
</pre>
<p>When validation error occurs get the message to show it to the user later:</p>
<pre class="brush: csharp;">
        void OnValidationError(object sender, System.Xml.Schema.ValidationEventArgs e)
        {
            validationErrors.Add(e.Message);
        }
 </pre>
<p>When xml document has been created and validated get the list of items:</p>
<pre class="brush: csharp;">
           public IList&lt;string&gt; GetOrderDetailsFromXML(string xmlString)
           {
             ...
            foreach (XmlNode position in doc.DocumentElement.ChildNodes)
            {
                StringBuilder positionInfo = new StringBuilder();

                // Read 'Product' and 'Amount' nodes.
                foreach (XmlNode item in position.ChildNodes)
                {
                    positionInfo.Append(item.InnerText);
                    positionInfo.Append('\t');
                }

                result.Add(positionInfo.ToString());
            }

            return result;
           }
 </pre>
<p>That&#8217;s it.<br />
<img class="aligncenter size-full wp-image-98" title="Screenshot" src="http://dmitrykiev.files.wordpress.com/2009/10/screenshot.png?w=913&#038;h=729" alt="Screenshot" width="913" height="729" /><br />
<a href="http://sites.google.com/site/thecodestuff/file-cabinet/OrdersHelperApplication.rar">Download</a> source code.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dmitrykiev.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dmitrykiev.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dmitrykiev.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dmitrykiev.wordpress.com&amp;blog=8616169&amp;post=43&amp;subd=dmitrykiev&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dmitrykiev.wordpress.com/2009/10/20/orders-viewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/73a792431da4ad27ccbd83910b88499b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dmitrykiev</media:title>
		</media:content>

		<media:content url="http://dmitrykiev.files.wordpress.com/2009/10/screenshot.png" medium="image">
			<media:title type="html">Screenshot</media:title>
		</media:content>
	</item>
	</channel>
</rss>
