<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Jaycent Drysdale</title><subtitle type="html" /><id>http://weblogs.asp.net/jaycentdrysdale/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/jaycentdrysdale/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2007-07-12T11:06:00Z</updated><entry><title>List&lt;t&gt; paging via LINQ to Objects</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2009/07/13/list-lt-t-gt-paging-via-linq-to-objects.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2009/07/13/list-lt-t-gt-paging-via-linq-to-objects.aspx</id><published>2009-07-13T11:01:00Z</published><updated>2009-07-13T11:01:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;The various grid controls shipped with asp.net provides plug and play data paging on its underlying data source. Its quiet simple to get a paged view of your data by setting a few properties on the grid before calling the Bind() method to connect your grid to the data.&amp;nbsp; This scenario works well in most situations. On occasions where the paging logic needs to reside outside of the UI layer, a more custom paging mechanism is required.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In this post, I'll examine a simple way to implement a custom paginging mechanism via LINQ to objects, removing the paging logic from the UI component and placing it at a lower level layer, maybe in a controller class (MVC) or in a presenter class in an MVP pattern.&lt;BR&gt;&lt;BR&gt;Lets imagine we have just retrieved a list of 5,000 rows of data from a product catalog table living in a SQL Server 2005 database, via&amp;nbsp;a &lt;STRONG&gt;&lt;EM&gt;datatable&lt;/EM&gt;&lt;/STRONG&gt; object. The data retrieved is broken out into the following columns:&lt;BR&gt;&lt;BR&gt;ProductId (int)&lt;BR&gt;Name (string)&lt;BR&gt;Description (string)&lt;BR&gt;Price (decimal)&lt;BR&gt;Category (string)&lt;/P&gt;We first need to convert this datatable object to a&amp;nbsp;strongly typed list of product summaries (each row in the datatable = a product summary)&lt;BR&gt;&lt;BR&gt;Lets define a product summary class that we can map each product to:&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; ProductId { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Name { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Description { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;decimal&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Price { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Category { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;&lt;BR&gt;We will also define another method that takes the datatable object and convert it into a strongly typed list of ProductSummary Instances.&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; ConvertTableToList(&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;DataTable&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; aDataTable)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; _lst = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;foreach&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;DataRow&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;aDataRow &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;in&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; aDataTable.Rows)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; aSummary = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aSummary.Category = aDataRow[&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"category"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;].ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aSummary.Description = aDataRow[&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"description"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;].ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aSummary.Name = aDataRow[&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"name"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;].ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aSummary.Price = (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;decimal&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;)aDataRow[&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"price"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aSummary.ProductId = (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;)aDataRow[&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"productid"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _lst.Add(aSummary);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; _lst;&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;So far we have created a class ProductSummary that will hold a row of data from our datatable. We have also defined a method called ConvertTableToList that will take our datatable object and convert it into a list of Productsummary objects.&lt;BR&gt;&lt;BR&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; GetProducts(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;? page, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;? pageSize)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //default to page 1 if no page supplied&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; _page = (page.HasValue) ? page.Value : 1;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DataTable dt = PupulateDataTable() &lt;FONT color=#008000&gt;//replace PopulateDataTable() with your logic to retrieve the data from the underlying data store&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008000 size=2&gt;&lt;FONT color=#008000 size=2&gt;//if no page size specified, set page size to total # of rows in data table&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; _pagesize = (pageSize.HasValue) ? pageSize.Value : dt.Rows.Count;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; lst = ConvertTableToList(dt);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008000&gt;//paging logic&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; l&lt;STRONG&gt;st.Skip((_page - 1) * _pagesize).Take(_pagesize).ToList();&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;BR&gt;}&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;And here is how we might access&amp;nbsp;a page of data from an asp.net web form page code-behind using the method defined above.&lt;BR&gt;Assume that our paging method was &amp;nbsp;defined in a class called &lt;STRONG&gt;&lt;EM&gt;Products.&lt;/EM&gt;&lt;/STRONG&gt; Here we are retrieving page one, and we are telling the method to return 50 rows of data per page.&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;List&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; products = &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;&lt;STRONG&gt;Products&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;.GetProducts(1, 50);&lt;BR&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;foreach&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;&lt;FONT color=#2b91af size=2&gt;ProductSummary&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; aSummary &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;in&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; products)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Write(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;.Format(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"{0} {1} [{2}]"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;,&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;&lt;FONT color=#a31515 size=2&gt;"&amp;lt;li&amp;gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;,aSummary.Name, aSummary.Category));&lt;BR&gt;}&lt;BR&gt;products = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P mce_keep="true"&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7146481" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="ASP.Net" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/ASP.Net/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="LINQ" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/LINQ/default.aspx" /></entry><entry><title>Generate RSS/Atom feeds using FeedManager.dll</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2009/01/01/rss-atom-syncication-feed-generator.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2009/01/01/rss-atom-syncication-feed-generator.aspx</id><published>2009-01-01T13:06:00Z</published><updated>2009-01-01T13:06:00Z</updated><content type="html">&lt;p&gt;FeedManager is a custom RSS/Atom Syndication generator&amp;nbsp;that allows for&amp;nbsp;quick and efficient generation of RSS/Atom feeds.&amp;nbsp;Just reference the dll in your web applications, then write a few lines of code to expose your data to external applications/web sites.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://www.codeplex.com/ASPNETRSSToolkit/Wiki/View.aspx?title=Consuming%20Feeds%20with%20a%20Build%20Provider" target="_blank" mce_href="http://www.codeplex.com/ASPNETRSSToolkit/Wiki/View.aspx?title=Consuming%20Feeds%20with%20a%20Build%20Provider"&gt;rsstoolkit&lt;/a&gt; exists for generating syndicated feeds on the fly, but if, like me, you have had issues porting the toolkit between project types and have to keep messing with web.config settings to get it to work, then the feedmanager.dll approach might work for you.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;Here's how to get started:&lt;br&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the cutsom &lt;a href="http://weblogs.asp.net/blogs/jaycentdrysdale/FeedManager.zip" class="" mce_href="http://weblogs.asp.net/blogs/jaycentdrysdale/FeedManager.zip"&gt;FeedManager.dll here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add a reference to the dll from your solution, or simply copy the file to your application's Bin directory&lt;/li&gt;
&lt;li&gt;Open up a web page, and in the code behind, create an instance of the FeedManager.FeedCreator class&lt;/li&gt;
&lt;li&gt;Set Properties on the FeedCreator class (title, author etc)&lt;/li&gt;
&lt;li&gt;Add FeedItems to the FeedCreator class. This will typically be data obtained from a dataset.&lt;/li&gt;
&lt;li&gt;Call the GenerateFeed() Method on the FeedManager.FeedCreator class to generate your feed.&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;    &lt;b&gt;protected void Page_Load(object sender, EventArgs e)&lt;br&gt;    {&lt;br&gt;       using (FeedManager.FeedCreator aFeed = new FeedManager.FeedCreator(FeedType.RSS))&lt;br&gt;       {&lt;br&gt;          aFeed.FeedUrl = "http://www.solid2.com";&lt;br&gt;          aFeed.FeedTitle = "My RSS Feed Title";&lt;br&gt;          aFeed.FeedDescription = "My RSS Feed Description";&lt;br&gt;          aFeed.FeedCopyright = "(c) 2009. All rights reserved";&lt;br&gt;          aFeed.FeedImage = "http://contoso/image.jpg";&lt;br&gt;&lt;br&gt;          //add items to the feed&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "first Item", "first summary", "Lorem ipsum dolor sit amet.", "thefirstlink", "1.aspx", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "second Item", "second summary", "Lorem ipsum dolor sit amet.", "thesecondlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "third Item", "third summary", "Lorem ipsum dolor sit amet.", "thethirdlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "fourth Item", "fourth summary", "Lorem ipsum dolor sit amet.", "thefourthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "fifth Item", "fifth summary", "Lorem ipsum dolor sit amet.", "thefifthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;          aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "sixth Item", "sixth summary", "Lorem ipsum dolor sit amet.", "thesixthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));&lt;br&gt;&lt;br&gt;          //generate the feed, send results to browser window.&lt;br&gt;          aFeed.GenerateFeed();&lt;br&gt;       }&lt;br&gt;    }&lt;/b&gt;
&lt;/pre&gt;
&lt;p mce_keep="true"&gt;Navigate to the page to view the ouput!&amp;nbsp;&lt;/p&gt;
&lt;p mce_keep="true"&gt;Play around with setting the FeedType setting in the constructor between Feedtype.RSS and FeedType.Atom. View the source of the generated file to examine the difference in the output. For an excellent comparison article for ATOM vs RSS, see &lt;a href="http://www.problogger.net/archives/2006/03/30/rss-vs-atom-whats-the-big-deal/" class="" title="as" target="_blank" mce_href="http://www.problogger.net/archives/2006/03/30/rss-vs-atom-whats-the-big-deal/"&gt;&lt;i&gt;Aaron Brazell&lt;/i&gt;&amp;nbsp; article here&lt;/a&gt;.&lt;br&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div mce_keep="true"&gt;&lt;a href="http://weblogs.asp.net/blogs/jaycentdrysdale/FeedManager.zip" class="" mce_href="http://weblogs.asp.net/blogs/jaycentdrysdale/FeedManager.zip"&gt;Download the feedManager.dll here&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div mce_keep="true"&gt;For source code, contact &lt;a href="mailto:info@solid2.com"&gt;info@solid2.com&lt;/a&gt; or &lt;a href="mailto:jaycentdrysdale@hotmail.com"&gt;jaycentdrysdale@hotmail.com&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p mce_keep="true"&gt;&amp;nbsp;Happy new year, and happy programming!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6810749" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="ASP.Net" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/ASP.Net/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="Visual Studio" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Visual+Studio/default.aspx" /></entry><entry><title>System.Data.GenericClient : A custom Data Access Component</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/20/system-data-genericclient-a-custom-data-access-component.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/20/system-data-genericclient-a-custom-data-access-component.aspx</id><published>2008-02-20T10:18:00Z</published><updated>2008-02-20T10:18:00Z</updated><content type="html">&lt;P&gt;Developers often find&amp;nbsp;themselves having to connect to data in a variety of datasources ranging from&amp;nbsp;MS Access &amp;nbsp;to large scale relational databases such as Oracle, SQL Server, MySql etc.&amp;nbsp;Each different datasource type typically requires importing a different .Net provider-specific namespace for working wth a specific database. For instance,&amp;nbsp;to connect to&amp;nbsp;an Oracle Database the consuming application needs&amp;nbsp;to import the System.Data.OracleClient Namespace and&amp;nbsp;untilize&amp;nbsp;classes such as OracleCommand, OracleDateReader etcettera.&amp;nbsp;To connect to&amp;nbsp;SqlServer&amp;nbsp;applications&amp;nbsp;developers&amp;nbsp;import the &amp;nbsp;System.Data.SqlClient namespace into their applications and program against the classes provided by the namespace.&amp;nbsp; The net effect of&amp;nbsp;having multpile provider specific namespaces&amp;nbsp;is that your DAL components are rarely ever portable, with each different database type normally requiring provider specific code.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;System.Data.GenericClient&lt;/STRONG&gt; is a simple but generic custom built data access component that solves some of the issues outlined above. &lt;STRONG&gt;System.Data.GenericClient&lt;/STRONG&gt; provides a very simple but familiar API that can be configured declaratively in an application configuration file as well as programmatically in your DAL. Below I'll take a look at using &lt;STRONG&gt;System.Data.Generic&lt;/STRONG&gt; to connect to various datasources using a consistent API. &lt;/P&gt;
&lt;P&gt;Here's what you need to do to get started using &lt;STRONG&gt;System.Data.GenericClient&lt;/STRONG&gt; in your applications:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Download the zip file at the link provided below . Extract the contents, then add a reference in your application to the extracted&amp;nbsp;&lt;STRONG&gt;System.Data.GenericClient.dll&lt;/STRONG&gt; file.&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Open up your aspplications config file and declare an appsettings entry as shown below:&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;appSettings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;add&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;key&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;System.Data.GenericClient.DefaultConnectionStringName&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;mysqlConnectionString&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;appSettings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#000000&gt;Declare a connectionstring entry. Make sure the name of this connection string matches the appsettings entry value specified above. In this case, the connectionstring entry name should be specified as "mysqlConnectionString. Provide a valid MySql Connection string. See example below:&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;connectionStrings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;add&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;mysqlConnectionString&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;connectionString&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Network Address=serveradress;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Initial &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Catalog='mydb';User&amp;nbsp;Name='sa';Password='pwd'&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; providerName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MySql.Data.MySqlClient&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;connectionStrings&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#000000&gt;Write data access logic to connect to the database. Below is an example of how to return a datatable object from the datasource&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;using&lt;/FONT&gt;&lt;FONT size=2&gt; (System.Data.&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;GenericClient&lt;/FONT&gt;&lt;FONT size=2&gt; gClnt = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;GenericClient&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT size=2&gt;))&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gClnt.Command.CommandType = &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;CommandType&lt;/FONT&gt;&lt;FONT size=2&gt;.Text;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gClnt.Command.CommandText = &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"select * from employees"&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;using&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DataTable&lt;/FONT&gt;&lt;FONT size=2&gt; dt = gClnt.ExecuteDataTable())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;FONT size=2&gt;.dataGridView1.DataSource = dt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;FONT size=2&gt;
&lt;P&gt;The code snippet above shows how simple it is to use &lt;STRONG&gt;System.Data.GenericClient &lt;/STRONG&gt;to access data from mySQL in a provider independent format.&amp;nbsp; For each aditional&amp;nbsp;datasource your application needs to connect to, specify a valid connection string in the applications configuration file as outlined above, then specify a valid command text or stored procedure on&amp;nbsp;GenericClient's command object.&amp;nbsp;&lt;BR&gt;&lt;BR&gt;See below for a list of operations supported by the GenericClient object:&lt;BR&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;virtual&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; ExecuteNonQuery()&lt;BR&gt;Use this method to execute an update, insert or delete operation on&amp;nbsp;the underlying&amp;nbsp;datasource&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;virtual&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; ExecuteXML()&lt;BR&gt;Use this method to execute a query&amp;nbsp;on&amp;nbsp;the underlying&amp;nbsp;datasource. Returns data in xml format&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;virtual&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DataTable&lt;/FONT&gt;&lt;FONT size=2&gt; ExecuteDataTable()&lt;BR&gt;Use this method to execute a query&amp;nbsp;on&amp;nbsp;the underlying&amp;nbsp;datasource. Returns a datatable object&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;virtual&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; ExecuteScalar()&lt;BR&gt;Use this method to execute a query&amp;nbsp;on&amp;nbsp;the underlying&amp;nbsp;datasource. Returns a&amp;nbsp;scalar object&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;System.Data.GenericClient&lt;/STRONG&gt; remains a work in progress. In addition to the features highlighted above, you will find other features in the namespace. These and other features will be further refined and documented in future updates. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;File Download: &lt;A href="http://weblogs.asp.net/blogs/jaycentdrysdale/System.Data.GenericClient.zip" mce_href="http://weblogs.asp.net/blogs/jaycentdrysdale/System.Data.GenericClient.zip"&gt;System.Data.GenericClient.zip&lt;/A&gt;&amp;nbsp;&lt;BR&gt;&lt;BR&gt;Want a copy of the source code? Send email to &lt;A href="mailto:jaycentdrysdale@hotmail.com" mce_href="mailto:jaycentdrysdale@hotmail.com"&gt;jaycentdrysdale@hotmail.com&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5827297" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="General Software Development" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/General+Software+Development/default.aspx" /><category term="SQL Server" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/SQL+Server/default.aspx" /></entry><entry><title>File System search via LINQ to Objects</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/15/file-system-search-via-linq-to-objects.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/15/file-system-search-via-linq-to-objects.aspx</id><published>2008-02-15T16:21:00Z</published><updated>2008-02-15T16:21:00Z</updated><content type="html">&lt;p&gt;LINQ&amp;nbsp;provides a standard way for developers to query data in diverse locations, ranging from in memory objects, XML data, or relational data living in an SQL Server Database.Lets take a look at a scenario where we use Linq to objects to query a directory on the local drive for files that match a given extension, and show the results in a Datagrid control. &lt;/p&gt;
&lt;p&gt;Here is the plan of action for the application&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a function to return a list of all the files in a directory. &amp;nbsp;We will call this method GetFiles, it will take one string parameter representing the base search directory, and will return a strongly typed list of FileInfo Objects.&lt;/li&gt;
&lt;li&gt;Use Linq to Objects to filter the returned list for files that matches a user-specified file extension. &lt;/li&gt;
&lt;li&gt;Bind the results to a grid&lt;/li&gt;&lt;/ol&gt;Lets&amp;nbsp;start by taking a look at the GetFiles&amp;nbsp;function:&lt;br&gt;&lt;font color="#0000ff" size="2"&gt;&lt;br&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;static&lt;/font&gt;&lt;font size="2"&gt; System.Collections.Generic.&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;FileInfo&lt;/font&gt;&lt;font size="2"&gt;&amp;gt; GetFiles(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; sPath, &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; sFileExtension)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;DirectoryInfo&lt;/font&gt;&lt;font size="2"&gt; _dirInfo = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;DirectoryInfo&lt;/font&gt;&lt;font size="2"&gt;(sPath);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;return&lt;/font&gt;&lt;font size="2"&gt; System.Linq.&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;Enumerable&lt;/font&gt;&lt;font size="2"&gt;.ToList(_dirInfo.GetFiles(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt;.Format(&lt;/font&gt;&lt;font color="#a31515" size="2"&gt;"*{0}"&lt;/font&gt;&lt;font size="2"&gt;,sFileExtension), &lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;SearchOption&lt;/font&gt;&lt;font size="2"&gt;.AllDirectories));&lt;br&gt;}&lt;/font&gt;&lt;font size="2"&gt; 
&lt;/font&gt;&lt;p&gt;The GetFiles() function uses objects from the System.IO namespace to do the&amp;nbsp;heavy lifting of searching the file system. Results are returned in a strongly typed list of &lt;font color="#2b91af"&gt;FileInfo &lt;/font&gt;Objects.&lt;br&gt;&lt;br&gt;Next we will look at the code that calls the GetFiles method defined above, and uses Linq to&amp;nbsp;filter the list for the given file type. You would typically put this code in the click event for a button control on a windows form.&lt;br&gt;&lt;br&gt;&lt;font size="2"&gt;&lt;font color="#008000"&gt;//get all files contained in the path supplied by the user&lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;System.Collections.Generic.&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;FileInfo&lt;/font&gt;&lt;font size="2"&gt;&amp;gt; _theFiles = GetFiles(c:\myDirectory, ".doc");&amp;nbsp;&lt;/font&gt;&lt;font color="#008000" size="2"&gt; &lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font color="#008000" size="2"&gt;//we now have a list of files...next we use LINQ to query the file list and sort the results by name&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;var&lt;/font&gt;&lt;font size="2"&gt; _files = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;from&lt;/font&gt;&lt;font size="2"&gt; file &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;in&lt;/font&gt;&lt;font size="2"&gt; _theFiles&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;orderby&lt;/font&gt;&lt;font size="2"&gt; file.Name&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;select&lt;/font&gt;&lt;font size="2"&gt; file;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;this&lt;/font&gt;&lt;font size="2"&gt;.dataGridView1.DataSource = _files.ToList();&lt;br&gt;&lt;/font&gt;&lt;br&gt;And there you have it.&amp;nbsp;Note the use of the &lt;font color="#0000ff"&gt;orderby&lt;/font&gt;&amp;nbsp;clause to sort the results before you bind the results to the grid.&amp;nbsp;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5794996" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="Windows Forms" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Windows+Forms/default.aspx" /><category term="Orcas" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Orcas/default.aspx" /></entry><entry><title>Extension Methods: A simple example</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/12/extension-methods-a-simple-example.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/12/extension-methods-a-simple-example.aspx</id><published>2008-02-12T10:23:00Z</published><updated>2008-02-12T10:23:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;If you've been developing software for any significant lenght of time, chances are you have compiled(for want of a better word) a repository of helper functions that have, over time, become valuable to you as you make your way through various applications. Extension Methods allow us&amp;nbsp;to extend&amp;nbsp;our custom and existing CLR types to include new&amp;nbsp;functionality. These new functionality might already exist in the form of helper functions scattered throughtout our applications. For example, You might have a helper function that&amp;nbsp;converts a string value to Proper Case. Extension methods allow us to&amp;nbsp;"add" this&amp;nbsp;&lt;EM&gt;ToProperCase()&lt;/EM&gt; functionality to the primitive System.String&amp;nbsp;type as if it&amp;nbsp;were a built in method of the type.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;In this post, I'll share with you a simple example of how I used extension methods to extend the sealed System.DateTime native type to include a &lt;BR&gt;&lt;EM&gt;&lt;STRONG&gt;ToFriendlyDateString()&lt;/STRONG&gt;&lt;/EM&gt; method. Extension Methods are new in the .Net Framework 3.5.&lt;/P&gt;The idea behind the &lt;EM&gt;ToFriendlyDateString()&lt;/EM&gt; method&amp;nbsp;is representing dates in a user friendly way. For example, when&amp;nbsp;displaying a news article on a webpage,&amp;nbsp;&lt;BR&gt;you might want articles that were published one day ago to have their publish dates represented as "yesterday at 12:30 PM". Or if the article was publish today, &lt;BR&gt;show the date as "Today, 3:33 PM".&amp;nbsp;&lt;BR&gt;&lt;BR&gt;The code snippet below&amp;nbsp;shows the&amp;nbsp;logic that will represent our extension method. Note the&amp;nbsp;Namespace declaration, and the signature for the class definition. Note also the use of the &lt;EM&gt;this&lt;/EM&gt; keyword when describing the input parameter for the &lt;EM&gt;ToFriendlyDateString()&lt;/EM&gt; method.&amp;nbsp;I'll eloberate on these later in this discussion.&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;STRONG&gt;namespace&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;STRONG&gt; &lt;/STRONG&gt;Utils&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;public&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;Extensions&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; ToFriendlyDateString(&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size=2&gt;&lt;STRONG&gt; Date&lt;/STRONG&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; FormattedDate = &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;""&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; (Date.Date == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Today)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FormattedDate = &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Today"&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; (Date.Date == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Today.AddDays(-1))&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FormattedDate = &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Yesterday"&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;else&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; (Date.Date &amp;gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Today.AddDays(-6))&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // *** Show the Day of the week&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;FormattedDate = Date.ToString(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"dddd"&lt;/FONT&gt;&lt;FONT size=2&gt;).ToString();&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FormattedDate = Date.ToString(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"MMMM dd, yyyy"&lt;/FONT&gt;&lt;FONT size=2&gt;);&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;//append the time portion to the output&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT size=2&gt;FormattedDate += &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;" @ "&lt;/FONT&gt;&lt;FONT size=2&gt; + Date.ToString(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"t"&lt;/FONT&gt;&lt;FONT size=2&gt;).ToLower();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;FONT size=2&gt; FormattedDate;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;}&lt;/FONT&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;When creating extension methods, here are the rules&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRIKE&gt;You must&amp;nbsp;define a namespace for your class.&amp;nbsp; Utils in the snippet above &lt;/STRIKE&gt;(Namespaces are not a strict requirement, but good practice nevertheless)&lt;/LI&gt;
&lt;LI&gt;The class that contain the extension method must be decorated with the &lt;STRONG&gt;static&lt;/STRONG&gt; modifier, and its visibility must be &lt;STRONG&gt;public&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The class must contain a static member, which will act as the extension method. This method must be public and must take one or more parameters, the first which must be a derivitive of the type you are extending. The first parameter definition must be preceeded by the &lt;STRONG&gt;this&lt;/STRONG&gt; keyword&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by the &lt;A id=ctl00_rs1_mainContentContainer_ctl22 onclick="javascript:Track('ctl00_rs1_mainContentContainer_ctl00|ctl00_rs1_mainContentContainer_ctl22',this);" href="http://msdn2.microsoft.com/en-us/library/dk1507sz.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/dk1507sz.aspx"&gt;this&lt;/A&gt; modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a &lt;SPAN class=keyword&gt;&lt;STRONG&gt;using&lt;/STRONG&gt;&lt;/SPAN&gt; directive. See example below showing how we might use the &lt;EM&gt;ToFriendlyDateString()&lt;/EM&gt; method in our applications:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;using&lt;/FONT&gt;&lt;FONT size=2&gt; Utils;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;......&lt;/P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt; dt = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;(2008, 2, 10, 8, 48, 20);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(dt.ToFriendlyDateString());&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;For further details on Extension Methods, check out this MSDN link: &lt;A href="http://msdn2.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bb383977.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb383977.aspx&lt;/A&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5767351" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="CLR" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/CLR/default.aspx" /><category term="General Software Development" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/General+Software+Development/default.aspx" /></entry><entry><title>Object Oriented Programming Refresher</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/07/virtual-methods-and-abstract-classes.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/02/07/virtual-methods-and-abstract-classes.aspx</id><published>2008-02-07T14:59:00Z</published><updated>2008-02-07T14:59:00Z</updated><content type="html">&lt;P&gt;Recently I was challenged by a colleague who asked some very basic questions relating to object orient programming. I know these concepts very well, but sometimes you have to stop and think twice about them, especially if most often than not, you do not implement these concepts in your day to day programming activities. As developers, we&amp;nbsp;often find ourselves in situations where the need to get things out the door and into production tend to encourage us to not think about doing things the right way, but&amp;nbsp;instead, getting the work done in the least possible time.&amp;nbsp; Object Oriented concepts are something every&amp;nbsp;serious&amp;nbsp;developer should know inside out. Sure you can get by without practicing it, but&amp;nbsp;that&amp;nbsp;approach might come back to haunt you down the road.&lt;BR&gt;&lt;BR&gt;Classes are&amp;nbsp;the&amp;nbsp;foundation&amp;nbsp;of&amp;nbsp;Object Oriented Programming.&amp;nbsp;Business Logic code should be seperated into groups of related classes that satisfy a business&amp;nbsp;need. There should be a clear seperation of concerns. When planning a development strategy for our applications, we should at all times try to envision our applications as being seperated into three logical tiers. Strictly speaking, having three logical tiers doesnt dictate that our apps&amp;nbsp;must to be deployed physically as a three tier app...all the tiers could live on one one physical machine, or they could be deployed accross three different machines. They could also be deployed on multiple machines in the enterprise, in what is known as an n-tier architecture.&amp;nbsp; Our apps will perform much better when we distribute the processing requirements accross multiple machines...business logic components run on machine A, Data Access components run seperate machine, and the front end logic running on a clinet pc or web server somewhere else. Microsft Transaction Server, and now Enterpise Services can act as a broker for our components living in the data access and business logic tiers, and offer such services as transactions support,&amp;nbsp;object pooling, which promotes&amp;nbsp;better scaling applications.&lt;BR&gt;&lt;BR&gt;So, what is an abstract class. What is&amp;nbsp;a sealed class. What is the difference accessibility methods out there that I can apply to my classes and methods, and why do I need them? What are interfaces? when is it useful to use an interface? These are the questions that rolled through my head when I was first introduced to OOP years ago. Over time, as you develop more business level applications, the importance of these concepts become clearer.&lt;BR&gt;&lt;BR&gt;Inheritance is a pupular&amp;nbsp;term among the OOP purists. So what is Inheritance, and how does it relate to&amp;nbsp;OOP? Perhaps the best way to describe this would be to imagine a hypothetical situation where you are building an app that requires you to Mainatin a list of employee records. All employees must have an employeeID, they must have a first name, and they must have a departmentID etc. In addition, there are some employees&amp;nbsp;that work on a part-time basis, and some that&amp;nbsp;work full-time.&lt;BR&gt;&lt;BR&gt;Looking at the above scenario, we have indentified the need for an employee class to service our application.&amp;nbsp;but before we start building our employee class, we need to take a closer look at how that class will be implemented. There are common&amp;nbsp;features that all employees have, but there are also some features that are specific to&amp;nbsp; the&amp;nbsp;full-time employee&amp;nbsp;and others that are specific to the part-time employee. For instance, when we calculate the&amp;nbsp;monthly pay for&amp;nbsp;the full-time&amp;nbsp;employee, the logic might be different from what we do when we calculate the salary of&amp;nbsp;the&amp;nbsp;guy that is employed part-time.&amp;nbsp;&amp;nbsp;It might help if we define a baseline Employee class that contain the common functionality, properties etc, and then further extend these classes in other derived classes to inplement the specific functionality.&amp;nbsp;So at the root, we&amp;nbsp;might create an employee class,&amp;nbsp; and two derived&amp;nbsp;classes:&amp;nbsp;FullTimeEmployee and ParttimeEmployee. Both&amp;nbsp;these classes will&amp;nbsp;be based on the base&amp;nbsp;Employee class and will inherit&amp;nbsp;any functionality exposed, but will further provide indiviual methods that will be used to calculate an employee's salary. &lt;BR&gt;&lt;BR&gt;By marking our employee class as Abstract, we&amp;nbsp;are&amp;nbsp;marking it&amp;nbsp;as a class that cannot be instantiated directly...we are saying that this class exists only to be further refined through inheritance.&amp;nbsp;The exact opposite scenario to that would be to mark our class as&amp;nbsp;sealed, which would mean it cannot be further refined through&amp;nbsp;inheritance. &lt;/P&gt;
&lt;P&gt;The definition for our base employee class might look like this:&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;abstract&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Employee&lt;BR&gt;{&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;The definiton for the derived&amp;nbsp;classes might look like so:&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;sealed&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;PartTimeEmployee&lt;/FONT&gt;&lt;FONT size=2&gt;:&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Employee&lt;BR&gt;{}&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;sealed&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FullTimeEmployee&lt;/FONT&gt;&lt;FONT size=2&gt;:&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Employee&lt;BR&gt;{}&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;Selected&amp;nbsp;data and function members defined in the &lt;EM&gt;Employe&lt;/EM&gt;e class will&amp;nbsp;be avaialable in both the derived classes. Data Members such as firstname, lastname, deptID, employeeID are common to all&amp;nbsp;employees&amp;nbsp;are defined on the &lt;EM&gt;Employee&lt;/EM&gt; base class.&amp;nbsp;The &lt;EM&gt;Employee&lt;/EM&gt; base class will also contain a method called CalculateWages, which will contain no functionality,&amp;nbsp;but will tell any class that&amp;nbsp;implements the &lt;EM&gt;Employee&lt;/EM&gt; class that&amp;nbsp;it must implement a CalculateWages method. In the base class, the&amp;nbsp;signature for the calculateWages&amp;nbsp;Method might look like this:&amp;nbsp;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;abstract&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;decimal&lt;/FONT&gt;&lt;FONT size=2&gt; CalculateWages();&lt;/P&gt;&lt;/FONT&gt;The&amp;nbsp;CalculateWage() method in the base Employee class could alternatively be decorated with the &lt;STRONG&gt;virtual&lt;/STRONG&gt; modifier instead of&amp;nbsp;&lt;STRONG&gt;abstract&lt;/STRONG&gt;. The difference is that the &lt;STRONG&gt;virtual&lt;/STRONG&gt; modifier allows the base class to put implementation code in the method, and allows the derived class to decide wether or not it wants to override the implemementation provided by the base class. If the derived class wants to overide the method in the base class, it would implement the method using the following signature:&lt;BR&gt;&lt;BR&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;override&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;decimal&lt;/FONT&gt;&lt;FONT size=2&gt; CalculateWages()&lt;BR&gt;{}&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 
&lt;P mce_keep="true"&gt;The&amp;nbsp;scenario looked at&amp;nbsp;above describes a&amp;nbsp;very&amp;nbsp;simple example of how&amp;nbsp;we might&amp;nbsp;implement a simple employee class in one of our applications.&amp;nbsp;Of course, there is much more to object oriented programming,&amp;nbsp;to much&amp;nbsp;to be described in a single blog post. Of course, there are many different ways to implement OOP...for instance, the employee base class described above could be implemented as an interface instead of as an abstract class.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;In Part 2 of this 4 part series,&amp;nbsp;I'll take a look at&amp;nbsp;other class modifiers, and also some of the accessibility options that we have available for exposing our classes to the outside world and what they mean for our classes.&amp;nbsp;I'll&amp;nbsp;also take a look at Interfaces, and how they&amp;nbsp;can be used in the&amp;nbsp;Employee list management scenario described in this article.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5731021" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="Commerce Server" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Commerce+Server/default.aspx" /><category term="CLR" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/CLR/default.aspx" /><category term="General Software Development" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/General+Software+Development/default.aspx" /><category term="Windows Forms" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Windows+Forms/default.aspx" /></entry><entry><title>Anticipated new Data Types in Microsoft SQL Server 2008</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/31/anticipated-new-features-in-microsoft-sql-server-2008.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/31/anticipated-new-features-in-microsoft-sql-server-2008.aspx</id><published>2008-01-31T20:29:00Z</published><updated>2008-01-31T20:29:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;The next release of Microsoft SQL server, version 2008, promises a number of significant changes over its previous 2005 version release.&amp;nbsp; From a Developers perspective, there is much anticipation over the new data types that we will get to play with in our stored procedures and other database objects. I’ll go through some of the new data types in this post.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;New Date data types:&lt;BR&gt;&lt;/STRONG&gt;Date:-The new Date data type allows you to store dates without a time component from 0001-01-01 to 9999-01-01. This new type will lend itself well to situations where a date variable doesn’t need to have a time attached to it...like a date of birth field/variable. There is also the Time type, which as you might guess, stores a time value, minus a date portion. Already I'm seeing situations where these Data types would have saved me a few lines of code had hey been available earlier. Other new date types include DateTime2 and DatetimeOffset.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;BR&gt;&lt;STRONG&gt;New HierarchyId data type&lt;BR&gt;&lt;/STRONG&gt;According to the Microsoft documentation, the Hierarchyid is a new data type that can store values that represent nodes in a hierarchy tree. This data type, which has a flexible programming model, can be implemented as a Common Language Runtime User-Defined Type (CLR UDT). The CLR UDT exposes several efficient built-in methods for creating and operating on hierarchy nodes. I am eagerly awaiting further details on the use of this new type, but at first glance, it seems we will now be able to store the hierarchical metadata that describes things like menu trees etc in a format that is easily retrievable. Building menus etc could be as easy as binding a treeview control to a field returned from a database or web-method call. I hope my understanding of this new type is not too far off from what it actually is. Time will tell.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;UserDefined Table type:&lt;/STRONG&gt;&lt;BR&gt;Again, the Microsoft documentation described this new type as follows: A user-defined table type represents the definition of a table structure. You can use a user-defined table type to declare table-value parameters for stored procedures or functions. You can use this table type to declare table variables that are to be used in a batch or in the body of a stored procedure or function. To ensure that the data in the table type meets specific requirements, you should create unique constraints and primary keys on the table type. Actually, this is a neat addition. If I understand this correctly, we can pass in an array (table) of parameter items into a stored procedure as a unit. So instead of passing in 50 individual parameters into a Stored Procedure, It’s now possible to pass in a single UDT type that holds all 50 parameter bits that need to get to the Query.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;FILESTREAM storage&lt;BR&gt;&lt;/STRONG&gt;Now here is where it gets interesting. It’s now possible to store data directly to the file system on the server via the FILESTREAM data type. It allows you to store unstructured data directly in the file system. You can use the new storage type VARBINARY(MAX) FILESTREAM to define table columns and store large binary data as files in the file system instead of storing them as Binary Large Objects (Blobs). In addition, you can use T-SQL statements—SELECT, INSERT, UPDATE, or DELETE—to query and modify FILESTREAM data. You can use the rich set of streaming APIs provided by Win32 for better streaming performance, while maintaining transactional consistency. You can also apply SQL Server functionalities to FILESTREAM data such as triggers, full-text search, backup and restore, SQL permissions, Database Console Command (DBCC) checks, and replication.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Sparse Columns&lt;BR&gt;&lt;/STRONG&gt;Typically, if you have a column/field in your database table that is infrequently used, and contains a null value in most cases, the new Sparse Columns feature provides a more efficient way to represent these. &lt;BR&gt;&lt;BR&gt;In wrapping up, its also worth mentioning that the UDT types, introduced in SQL Server 2005, have undergone some changes in the 2008 release. Previously UDT types were limited a size of 8K....that limitation has been removed.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5683589" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="SQL Server 2008" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/SQL+Server+2008/default.aspx" /></entry><entry><title>Options for Database access outside of ADO.Net</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/29/options-for-database-access-outside-of-ado-net.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/29/options-for-database-access-outside-of-ado-net.aspx</id><published>2008-01-29T14:47:00Z</published><updated>2008-01-29T14:47:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;In the world of .NET programming, ADO.NET has become the De Facto standard for accessing database of all types (relational or otherwise). The purists among us will be quick to point out that ADO.Net should be the only option and that as developers we shouldn’t even be thinking about bypassing ADO.NET to get to our database. But the no-so-pure will be quick to point out the alternative methods for pulling data from our databases without writing a line of database code. If you are still reading this article, it means you, like your truly have had occasions in the past where bypassing ADO.Net makes sense, whether you are creating a small website for your wedding guest list, or just putting together a demo website of sorts.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;The SqlDataSource Control:&lt;BR&gt;&lt;/STRONG&gt;The SqlDataSource control (in my mind, the grand-daddy of declarative data Access) allows&amp;nbsp;for the&amp;nbsp;definition of&amp;nbsp;queries in a declarative way. You can connect the SqlDataSource to controls such as the Datalist, and give your users the option to edit and update data without requiring any ADO.NET code.&amp;nbsp; While the sqlDatasource control handles the heavy lifting required to facilitate the communication, it's worth mentioning that behind the scenes, it uses ADO.NET to do this heavy-lifting. The sqlDatasource supports any database that has a full ADO.NET provider. Apart from the fact that the sqlDatasource connects you to your database with minimal code, it does provide more benefits to developers who are looking to provide functionality such as paging sorting of datagrids without having to write lines of code to achieve this. If you bind your datagrid directly to a sqlDatasource control, you have paging and sorting functionality right at your fingertips.&amp;nbsp; You can get to it by&amp;nbsp;setting a few properties on your grid control. However, with all its "niceties" the SqlDataSource is somewhat controversial, because it encourages you to place database logic in the markup portion of your page. Many will agree that there are times when the benefits of using this control far outweigh this particular drawback.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;LINQ to SQL:&lt;BR&gt;&lt;/STRONG&gt;Linq provides us with cool new way of accessing data.&amp;nbsp; The source of this data can range from anything from files in your computer file system, a collection of objects living in a generic list in server memory, or rows of data residing in a database table in on the North Pole. Linq comes in a variety of flavors (LINQ to objects, LINQ to XML, LINQ to entities, LINQ to SQL, LINQ to Dataset).&amp;nbsp; With LINQ to SQL, you define a query using C# code (or the LinqDataSource control) and the appropriate database logic is generated automatically. LINQ to SQL supports updates, generates secure and well-written SQL statements, and provides some customizability. Like the SQLDataSource control, LINQ to SQL doesn’t allow you to execute database commands that don’t map to straightforward queries and updates &lt;BR&gt;(such as creating tables). Unlike the SqlDataSource control, LINQ to SQL only works with SQL Server and is completely independent of ADO.NET.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;Profiles: &lt;BR&gt;&lt;/STRONG&gt;The profiles feature, introduced in .Net Framework 2.0, allows&amp;nbsp;you to store user-specific blocks of data in a database without writing&lt;BR&gt;ADO.NET code.&amp;nbsp; You specify what data you want to gather and store by configuring the appropriate elements in your applications configuration file. &lt;/P&gt;
&lt;P mce_keep="true"&gt;In wrapping up, it’s worth mentioning that none of options presented in this article is a replacement for ADO.NET, because none of them offers the full flexibility, customizability, and performance that hand-written database code offers. However, depending on the specific needs of your application, it may be&lt;BR&gt;worth using one or more of these features to augment your ADO.Net centric data access layer.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5671498" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="ASP.Net" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/ASP.Net/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /><category term="SQL" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/SQL/default.aspx" /><category term="LINQ" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/LINQ/default.aspx" /></entry><entry><title>Enhance your apps with the Integrated ASP.Net Pipleline</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/23/running-php-apps-under-iis-7-0.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2008/01/23/running-php-apps-under-iis-7-0.aspx</id><published>2008-01-23T17:32:00Z</published><updated>2008-01-23T17:32:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;The January publication of MSDN Magazine carried an article titled "Enhance your apps with Integrated ASP.Net Pipleline".&amp;nbsp;While the subject of the article is not something that I would normally be super excited about, I decidede to spend at least 10 minutes perusing&amp;nbsp;the article while commuting to work this morning (Been riding the train past couple of weeks).&amp;nbsp; I recently installed Vista on my Notebook, and was keen to start looking into the features of IIS 7.0, which ships with microsoft's latest desktop operating system. &amp;nbsp;As it turned out, the article touched on a subject that might be useful down the road as we take a leap into the world of PHP programming at work.&lt;BR&gt;&lt;BR&gt;Its long been common knowledge that PHP could run under IIS, but not in a way that would make it feasible to run production apps...in other words, if you configure your PHP apps in IIS 6.0/5.0, the result would be a web site that runs very slow, if nothing else, due mainly to the lack of thread safety in PHP apps. Alternately, the app could be configured to run under IIS using CGI, but CGI is a resource hog (one process per request) and results in an app that&amp;nbsp;scale poorly in IIS.&lt;/P&gt;
&lt;DIV class=ms-PostBody&gt;
&lt;DIV&gt;
&lt;DIV class=ExternalClassE63B3BC1C6374403A4847CB64549C39E&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The latest version of IIS(7.0)&amp;nbsp;now allows for the targeting of none .Net Framework apps. Through its "FasstCGI" component, &amp;nbsp;core&amp;nbsp;ASP.Net&amp;nbsp;&amp;nbsp;features can now be used&amp;nbsp;declaratively in Apps written to target other Frameworks.&lt;BR&gt;&lt;BR&gt;For example, IIS 7 allows PHP, Ruby, Perl etc&amp;nbsp;to utilize the ASP.Net Integrated mode engine to take advantage of features like ASP.Net membership and forms authentication, login controls etc.&amp;nbsp; The new ASP.Net Integrated Pipeline feature of IIS 7.0 also allows us the ability to leverage our .net skills in applying cool features such as URL-rewriting,&amp;nbsp;Output caching&amp;nbsp;to these&amp;nbsp;none asp.net apps&amp;nbsp;by writing modules that can be plugged directly into the request processing pipeline via IIS. If you are unfortunate enough to be still running a couple of classic ASP pages within your .net Framework application, you will be releieved to know that IIS7.0 now makes it possible for these classic ASP pages to utilize functionality that per previously unavailable under IIS 5.x/ 6.&amp;nbsp;&lt;BR&gt;&lt;BR&gt;If you are developing under Windows Vista, you already have acccess to IIS 7.0. On the Server end, IIS 7.0 will be realeased with windows Server 2008 in Late February. The FastCGI component will be avaialable with this release of windows Server 2008, under Vista, its available via Service pack 1.&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5640319" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author><category term="Vista" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/Vista/default.aspx" /><category term="ASP.Net" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/ASP.Net/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/C_2300_/default.aspx" /><category term="IIS" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/IIS/default.aspx" /><category term=".NET" scheme="http://weblogs.asp.net/jaycentdrysdale/archive/tags/.NET/default.aspx" /></entry><entry><title>Web.Config: Multiple file configurations</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/jaycentdrysdale/archive/2007/07/12/web-config-multiple-file-configurations.aspx" /><id>http://weblogs.asp.net/jaycentdrysdale/archive/2007/07/12/web-config-multiple-file-configurations.aspx</id><published>2007-07-12T15:06:00Z</published><updated>2007-07-12T15:06:00Z</updated><content type="html">&lt;p&gt;ASP.NET Web.Config files provide a configuration system we can use to keep our applications flexible at runtime. In this article we will examine a simple technique for using the configuration system for the best results. &lt;/p&gt;
&lt;p&gt;The &amp;lt; appSettings &amp;gt; element of a web.config file is a place to store connection strings, server names, file paths, and other miscellaneous settings needed by an application to perform work. The items inside appSettings are items that need to be configurable depending upon the environment, for instance, any database connection strings that will change as our applications are moved from a testing/staging server into a production environment. &lt;/p&gt;
&lt;p&gt;Developers often find themselves having to take extra care not to overwrite web.config file as they move code from one environment to the next, typically from develeopment, to staging/testing, and finally to production. Let's take a look at a little known feature of the appSettings element that can give us even more flexibility (see source code in url below). &lt;/p&gt;
&lt;p&gt;The appSettings element may contain a file attribute that points to an external file.If the external file is present, ASP.NET will combine the appSettings values from web.config with those in the external file. If a key/value pair is present in both files, ASP.NET will use the value from the external file. &lt;/p&gt;
&lt;p&gt;This feature is useful when you keep user-specific or environment-specific settings in the external file. Let web.config contain those settings that are global to all the installed instances of your application, while each user or installed site contains their own settings in an external file. This approach makes it easier to move around global web.config changes and keep web.config checked into source control, while each developer can get their own settings separate. &lt;/p&gt;
&lt;p&gt;One caveat to this approach is that the ASP.NET runtime does not detect when the external file changes. You’ll need to make changes to web.config itself for ASP.NET to launch a new version of the application with all changes in effect. &lt;/p&gt;
&lt;p&gt;In the attached code snippet (see link below), lines 2 through 8 shows a typical implemention of a web.config file that points to an external configuration file. Lines 13 through 15 shows what the external file might look like.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jaycentdrysdale.com/articles/code_display.aspx?codeid=adedb5b5-ca86-4dbe-9c5e-1a16dd45b292" mce_href="http://www.jaycentdrysdale.com/articles/code_display.aspx?codeid=adedb5b5-ca86-4dbe-9c5e-1a16dd45b292"&gt;http://www.solid2.com/jaycent/articles/code_display.aspx?codeid=adedb5b5-ca86-4dbe-9c5e-1a16dd45b292&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5671568" width="1" height="1"&gt;</content><author><name>jaycent</name><uri>http://weblogs.asp.net/members/jaycent.aspx</uri></author></entry></feed>