<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Aiken : WCF</title><link>http://blogs.msdn.com/daiken/archive/tags/WCF/default.aspx</link><description>Tags: WCF</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>LINQ and WCF Syndication</title><link>http://blogs.msdn.com/daiken/archive/2008/01/28/linq-and-wcf-syndication.aspx</link><pubDate>Tue, 29 Jan 2008 10:44:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7300895</guid><dc:creator>daiken</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/daiken/comments/7300895.aspx</comments><wfw:commentRss>http://blogs.msdn.com/daiken/commentrss.aspx?PostID=7300895</wfw:commentRss><description>&lt;p&gt;I must admit, having survived the last 22 data access technologies, I'm really liking LINQ. The fact that I can use LINQ to query just about anything, against just about any data source is pretty cool. Lists and Arrays beware. Nested Correlated sub-queries are near - I also love to hear &lt;a href="http://channel9.msdn.com/Showpost.aspx?postid=357683" target="_blank"&gt;Luca&lt;/a&gt; speak about it.&lt;/p&gt;  &lt;p&gt;Anyway, while preparing the latest DinnerNow release (coming soon), I had to rewrite the RSS feed for the restaurant. Obviously using the Syndication Support in WCF.&lt;/p&gt;  &lt;p&gt;Since the Feed is simply returning menu items, you can imagine its a simple database call to return the menu items, then a loop to create syndication feed items for each one, then spit them out. Fine, but with LINQ, you can miss most of that out. In fact when I originally wrote this, it had 1 line of code which returned the results of a LINQ query. Some people thought this might be too much so I split it into many more lines as shown below.&lt;/p&gt;  &lt;p&gt;Key in creating the Syndication items is line 15, as part of the LINQ query. The query projects directly into SyndicationItems. Note also the Links property being populated on line 27 - all pretty neat.&lt;/p&gt;  &lt;p&gt;Since the feed type (atom or rss) is simply formatting, I actually specified this as a parameter and lines 37 to 39 work out which formatter to use, based upon the URL.&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; System.ServiceModel.Syndication.SyndicationFeedFormatter GetMenuItems(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; feedType, &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; restaurantName, &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; menuType)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;     var db = &lt;span class="kwrd"&gt;new&lt;/span&gt; DinnerNowDataContext();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;     Uri incomingURI = (OperationContext.Current == &lt;span class="kwrd"&gt;null&lt;/span&gt; ? &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(&lt;span class="str"&gt;&amp;quot;http://localhost/&amp;quot;&lt;/span&gt;) : &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        OperationContext.Current.IncomingMessageHeaders.To);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;     var items = from mi &lt;span class="kwrd"&gt;in&lt;/span&gt; db.MenuItems.AsEnumerable()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;where&lt;/span&gt; ((mi.Menu.Restaurant.Name == restaurantName) &amp;amp;&amp;amp; (mi.Menu.MenuType.Trim() == menuType))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        orderby mi.Name&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        select &lt;span class="kwrd"&gt;new&lt;/span&gt; SyndicationItem()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            Title = SyndicationContent.CreatePlaintextContent(mi.Name),&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            PublishDate = DateTime.MinValue,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            LastUpdatedTime = DateTime.MinValue,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            Id = mi.MenuId.ToString(),&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            Content = &lt;span class="kwrd"&gt;new&lt;/span&gt; TextSyndicationContent(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        String.Format(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            CultureInfo.CurrentCulture,&lt;span class="str"&gt;@&amp;quot;&amp;lt;p&amp;gt;{0}&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;lt;img src='{1}/{2}' style='border: 0px;width:216px;height:174px;' /&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                        mi.Description,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                        &lt;span class="str"&gt;&amp;quot;/DinnerNow&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;                        mi.ImageLocation), TextSyndicationContentKind.Html),&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            Links = { SyndicationLink.CreateAlternateLink(&lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(incomingURI.AbsoluteUri + &lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; + mi.Name)) }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;         };&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;     SyndicationFeed feed = &lt;span class="kwrd"&gt;new&lt;/span&gt; SyndicationFeed(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="str"&gt;&amp;quot;DinnerNow - Menu Items&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="str"&gt;&amp;quot;Menu Items for Restaurant&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        incomingURI,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        items.ToList&amp;lt;SyndicationItem&amp;gt;()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        );&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;     &lt;span class="kwrd"&gt;return&lt;/span&gt; (feedType.ToLower(CultureInfo.CurrentCulture).Equals(&lt;span class="str"&gt;&amp;quot;atom&amp;quot;&lt;/span&gt;) ?&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        (&lt;span class="kwrd"&gt;new&lt;/span&gt; Atom10FeedFormatter(feed)) &lt;span class="kwrd"&gt;as&lt;/span&gt; SyndicationFeedFormatter :&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; Rss20FeedFormatter(feed));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Below is the contract, so you can see how the URL is put together. Something like http://localhost/DinnerNow/service/menussearchservice.svc/rss/restaurants/NorthWind/Dinner would activate the service.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[OperationContract]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;[WebGet(UriTemplate = &lt;span class="str"&gt;@&amp;quot;/{feedType}/restaurants/{restaurantName}/{menuType}&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;SyndicationFeedFormatter GetMenuItems(&lt;span class="kwrd"&gt;string&lt;/span&gt; feedType, &lt;span class="kwrd"&gt;string&lt;/span&gt; restaurantName, &lt;span class="kwrd"&gt;string&lt;/span&gt; menuType);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Minus the contract, there really is only 5 lines of code - albeit split into multiple lines. Whilst this in itself is not that cool, the fact my code is no longer plagued with mind-numbing foreach loops is an absolute blessing. (re-write the above using ADO.NET if you want to see what I mean)&lt;/p&gt;

&lt;p&gt;Long Live LINQ...&lt;/p&gt;

&lt;p&gt;Note: this post was never meant to be a tutorial, simply a look how cool this is...&lt;/p&gt;

&lt;p&gt;THIS POSTING IS PROVIDED &amp;quot;AS IS&amp;quot; WITH NO WARRANTIES, AND CONFERS NO RIGHTS &lt;/p&gt;

&lt;p&gt;EVEN IF YOU HAVE A NOTE FROM YOUR MUM&lt;/p&gt;

&lt;p&gt;&lt;font face="Consolas" color="#000000" size="2"&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7300895" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/daiken/archive/tags/General/default.aspx">General</category><category domain="http://blogs.msdn.com/daiken/archive/tags/DinnerNow/default.aspx">DinnerNow</category><category domain="http://blogs.msdn.com/daiken/archive/tags/WCF/default.aspx">WCF</category></item></channel></rss>