<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
  <channel>
    <title>dotNetProfessional</title>
    <description>Garry McGlennon</description>
    <link>http://www.dotnetprofessional.com/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.4.5.0</generator>
    <language>en-AU</language>
    <blogChannel:blogRoll>http://www.dotnetprofessional.com/blog/opml.axd</blogChannel:blogRoll>
    <dc:creator>Garry McGlennon</dc:creator>
    <dc:title>dotNetProfessional</dc:title>
    <item>
      <title>New promo video for ezyTip</title>
      <description>&lt;p&gt;&lt;a href="http://bit.ly/b4RuLH"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="promovideo" border="0" alt="promovideo" align="right" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/NewpromovideoforezyTip/12E2E849/promovideo.jpg" width="240" height="139" /&gt;&lt;/a&gt;The original promo video I did was kinda crap so I spent a few nights trying to do something a little more polished and interesting, and I think the results are fairly good. For those interested in doing a similar type of promo for your Apps, here’s the technique I used. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Write your basic script with timings, I tried to make all descriptions to be on screen for at least 4 seconds to allow time for the viewer to read them.&lt;/li&gt;    &lt;li&gt;Use a screen capture program such as Expression Encoder screen capture and run through your script as you use your application in the emulator.&lt;/li&gt;    &lt;li&gt;Using blend create a single storyboard and create your animations tying the storyboard timeline to your videos timeline. You can embed your video as a media element. You won’t get the video to run in preview mode in blend, so have it running in Windows Media player to sync the timelines.&lt;/li&gt;    &lt;li&gt;Then run the Blend App (I used a SL App) and again use your screen capture program. Then if you used Expression Encoders screen capture send it to Expression Encoder and encode for YouTube.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That’s the basic steps I used to create the video and it took me a while to settle on this technique having first tried Power Point and other more complex Silverlight options, but this one seems quite easy to use and provides a huge amount of powerful flexibility.&lt;/p&gt;  &lt;p&gt;I’ll be doing another one when I’m ready to release my next App which should appeal to a much wider audience than the &lt;a href="http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank"&gt;ezyTip&lt;/a&gt; Application.&lt;/p&gt;  &lt;p&gt;Oh the final result can be found here: &lt;a href="http://bit.ly/b4RuLH"&gt;ezyTip for Windows Phone 7&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx&amp;amp;title=New promo video for ezyTip" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx&amp;amp;title=New promo video for ezyTip" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx&amp;amp;title=New promo video for ezyTip" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=30324bec-206a-4389-bcef-df39dfd67da3</guid>
      <pubDate>Sat, 16 Oct 2010 23:24:25 +0000</pubDate>
      <category>Windows Phone 7</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=30324bec-206a-4389-bcef-df39dfd67da3</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=30324bec-206a-4389-bcef-df39dfd67da3</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/10/16/New-promo-video-for-ezyTip.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=30324bec-206a-4389-bcef-df39dfd67da3</wfw:commentRss>
    </item>
    <item>
      <title>ezyTip for Windows Phone 7</title>
      <description>&lt;p&gt;&lt;a href="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsPhone7/31D782C6/mkt_lg.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 5px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ezyTip Windows Phone 7" border="0" alt="ezyTip Windows Phone 7" align="right" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsPhone7/1F22890F/mkt_lg_thumb.png" width="173" height="173" /&gt;&lt;/a&gt; Over the past few months I’ve been working on two applications for the soon to be released Windows Phone 7 platform. I’ve been lucky enough to have gotten a real device and that has proved invaluable for both of the Apps, in both performance and visuals (the physical device only supports 16bpp – translation don’t do gradients!). The first of my Apps ezyTip has been approved for early ingestion so it will be ready for launch (when ever that is). I’ve posted a short &lt;a href="http://bit.ly/b4RuLH"&gt;preview video&lt;/a&gt; of the new App (though I’ve made some cosmetic changes already) if anyone is interested in having a look. &lt;/p&gt;  &lt;p&gt;The reason I originally chose to write ezyTip for the 6.x device was to try something that would be simple at first. Well on the 6.x device that proved to be quite hard, however doing the same version on WP7 has proved to be much easier (though not without its challenges!), and has allowed the introduction of more animations. The App has been a complete rewrite so I could make use of better development patterns, though much of the artwork is identical.&lt;/p&gt;  &lt;p&gt;I’m excited to see the launch of Windows Phone 7 and already I can see a number of Apps starting to fill up the App Store (already see a few tip calculators!), so I think you can expect to see a fair number when you pickup your device in a month. I continue to work on the next app which is not an easy one and is one which I hope will be a real asset to the platform. I’ll be blogging about that one as it starts to take shape.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx&amp;amp;title=ezyTip for Windows Phone 7" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx&amp;amp;title=ezyTip for Windows Phone 7" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx&amp;amp;title=ezyTip for Windows Phone 7" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=4f4815db-0512-4f9a-a6b5-7b6df2398b23</guid>
      <pubDate>Fri, 08 Oct 2010 19:08:10 +0000</pubDate>
      <category>Windows Phone 7</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=4f4815db-0512-4f9a-a6b5-7b6df2398b23</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=4f4815db-0512-4f9a-a6b5-7b6df2398b23</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/10/08/ezyTip-for-Windows-Phone-7.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=4f4815db-0512-4f9a-a6b5-7b6df2398b23</wfw:commentRss>
    </item>
    <item>
      <title>Debug Memory Counter for Windows Phone 7</title>
      <description>&lt;p&gt;For anyone doing any type of Windows Phone 7 development, you would have come across the debug counters that Microsoft ship, and if you' haven’t then I’d suggest checking this &lt;a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/13/building-high-performance-silverlight-apps-on-windows-phone-7.aspx" target="_blank"&gt;blog post&lt;/a&gt; which discusses the performance whitepaper Microsoft released.&lt;/p&gt;  &lt;p&gt;While these counters are great and essential to any development, they do miss a few things. One of the most notable is a memory counter! This is arguably one of the most important counters to have on a memory constrained device. Also your app is only allowed to take about 80-90Meg of RAM before you’re in trouble, so you need to know this number, especially if you’re doing anything graphic intensive.&lt;/p&gt;  &lt;p&gt;So to rectify this issue, I’ve built one which works in essentially the same way as the shipped ones. You simply add one line of code to the start up page and you’ll see the counter update every 2 seconds by default. I’ve also make it so you can specify the interval in seconds if you prefer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/DebugMemoryCounterforWindowsPhone7/022A99EA/MemoryCounter.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; margin: 20px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MemoryCounter" border="0" alt="MemoryCounter" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/DebugMemoryCounterforWindowsPhone7/216D40BD/MemoryCounter_thumb.png" width="295" height="59" /&gt;&lt;/a&gt;As can be seen in the image it will tell you the Total Memory, Peak Memory (the most you’ve used) and the most important the current amount of memory being used.&lt;/p&gt;  &lt;p&gt;To get this working simply add a reference to the supplied dll (see link at the end of the post) and then add the following line of code to your start-up page:&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dnp.Counter.EnableMemoryCounter = true;&lt;/p&gt;  &lt;p&gt;If you want to specify the duration of the counter then you set it using this line of code, which specifies every 10 seconds:&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dnp.Counter.SetTimerInterval(10);&lt;/p&gt;  &lt;p&gt;That’s it, if you’d like to leave a comment you can do so on the forums as I seem to get too much spam when I open the comments section up. You can find a &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/6b04e48e-614f-4ecf-a994-343d9e3e4da3" target="_blank"&gt;forum post about this counter here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Also, I wish to thank Stefan W. for the help he provided in getting this counter working!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Download: &lt;a href="http://dotnetprofessional.com/blog/file.axd?file=2010%2f9%2fdnp.Counters.dll"&gt;dnp.Counters.dll (37.50 kb)&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx&amp;amp;title=Debug Memory Counter for Windows Phone 7" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx&amp;amp;title=Debug Memory Counter for Windows Phone 7" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx&amp;amp;title=Debug Memory Counter for Windows Phone 7" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=2a81a22c-260e-4144-8f70-128f673fa558</guid>
      <pubDate>Mon, 27 Sep 2010 22:53:21 +0000</pubDate>
      <category>Windows Phone 7</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=2a81a22c-260e-4144-8f70-128f673fa558</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=2a81a22c-260e-4144-8f70-128f673fa558</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/09/27/Debug-Memory-Counter-for-Windows-Phone-7.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=2a81a22c-260e-4144-8f70-128f673fa558</wfw:commentRss>
    </item>
    <item>
      <title>Custom Per-Page Transitions for Windows Phone 7</title>
      <description>&lt;p&gt;I’ve been looking for a way to create custom transitions for the Apps I’m writing for Windows Phone 7 and came across this informative &lt;a href="http://channel9.msdn.com/posts/SlickThought/Custom-Per-Page-Transitions-for-Windows-Phone-7/" target="_blank"&gt;post and video&lt;/a&gt;. Where they describe how to create custom transitions for per page navigation. The only issue is it hasn’t been updated for the Beta release. So I took 10 mins (with the help of ReSharper) to upgrade it to the new Beta, so others don't have to go through the work. I’m not sure if its my machine, but the transitions in the emulator looked a bit sluggish, however I tried them out on a device and they seemed smooth.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/downloads/FindAZip-CustomTransitions-Beta.zip" target="_blank"&gt;FindAZip-CustomTransitions-Beta.zip&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx&amp;amp;title=Custom Per-Page Transitions for Windows Phone 7" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx&amp;amp;title=Custom Per-Page Transitions for Windows Phone 7" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx&amp;amp;title=Custom Per-Page Transitions for Windows Phone 7" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=b04ffd4e-142b-4197-8f81-ce4401380e3e</guid>
      <pubDate>Tue, 17 Aug 2010 23:12:35 +0000</pubDate>
      <category>Windows Phone 7</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=b04ffd4e-142b-4197-8f81-ce4401380e3e</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=b04ffd4e-142b-4197-8f81-ce4401380e3e</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/08/17/Custom-per-page-page-transitions-for-Windows-Phone-7-updated-to-Beta.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=b04ffd4e-142b-4197-8f81-ce4401380e3e</wfw:commentRss>
    </item>
    <item>
      <title>Performance Optimization on Windows Phone 7</title>
      <description>&lt;p&gt;Its been awhile since I put up a blog post and that’s partly due to being so busy working on my two Windows Phone 7 Apps. Which brings me to the topic of this post and one which I think is important for fellow devs to understand. I am one of the lucky few that have received a real device and its very nice! :)&amp;#160; (thanks Microsoft!) &lt;/p&gt;  &lt;p&gt;One of the first things I started to do was performance test my App on the device and found that the device is a &lt;strong&gt;lot &lt;/strong&gt;slower than the emulator. So I started to run some optimizations and wrote a small benchmark App to help me work out which refactorings were the fastest. I was rather pleased with myself when I ended up getting improvements of 200 and 300%! in the emulator. Then thought I’d see how much of that new gain transferred to the device. The results shocked the hell out me, as rather than getting a gain I ended up with a lost of 50%! That’s right my optimizations did the exact opposite of what they were supposed to do.&lt;/p&gt;  &lt;p&gt;My code processes millions of bytes and applies math during that process, some of which was using floating point math. The optimizations were designed to remove the floating point math completely in favor of integer math, because as we all know floating point math is slow right? Well it seems in the emulator that statement holds true however it didn’t seem to hold true for the actual device. To investigate this further I wrote a small app which benchmarked floating point vs integer math (simple multiplications &amp;amp; divisions). Here’s the results for both the emulator and the real device. Both are release builds not attached to the debugger.&lt;/p&gt;  &lt;h2&gt;Results&lt;/h2&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="80"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;Multiply           &lt;br /&gt;Emulator&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;Multiply           &lt;br /&gt;Device&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;Division           &lt;br /&gt;Emulator&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;Division           &lt;br /&gt;Device&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="80"&gt;&lt;strong&gt;Integer&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;font color="#00ff00"&gt;&lt;strong&gt;&lt;font color="#0080c0"&gt;1,772ms&lt;/font&gt; &lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;11,174ms&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;&lt;font color="#0080c0"&gt;12,890ms&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;font color="#0080c0"&gt;&lt;strong&gt;79,376ms&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="80"&gt;&lt;strong&gt;Double&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;6,651ms&lt;/td&gt;        &lt;td valign="top" width="80"&gt;&lt;strong&gt;&lt;font color="#0080c0"&gt;10,390ms&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;47,898ms&lt;/td&gt;        &lt;td valign="top" width="80"&gt;135,455ms&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="80"&gt;&lt;strong&gt;Gain of fastest&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="80"&gt;275.34%         &lt;br /&gt;(integer)&lt;/td&gt;        &lt;td valign="top" width="80"&gt;7.55 %         &lt;br /&gt;(double)&lt;/td&gt;        &lt;td valign="top" width="80"&gt;271.59%         &lt;br /&gt;(integer)&lt;/td&gt;        &lt;td valign="top" width="80"&gt;70.65%         &lt;br /&gt;(integer)&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;em&gt;&lt;font size="1"&gt;based on 200,000,000 iterations&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;So by swapping out any double multiplications for a few integer multiplications we end up suffering badly as on the device they are roughly equal. However, the device seems to handle double divisions better and will yield a 70% gain if you use integer division math over double math. However, a great performance gainer is if you don’t need absolute precision try using the reciprocal of a number and multiply rather than divide. Ie say you want to divide a number by 255, instead multiply the number by (1/255), you can use a double variable to hold that result and then use it in your math. &lt;strong&gt;This alone can provide a gain of 500% on the emulator and a whopping 1,100% gain on the device!!&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;Be very careful about performance optimizations especially if you attempt to eliminate floating point math in favor of integer math if you don’t have a physical device. Try where you can to substitute a divide with a floating point multiply for a super-charged performance gain.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx&amp;amp;title=Performance Optimization on Windows Phone 7" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx&amp;amp;title=Performance Optimization on Windows Phone 7" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx&amp;amp;title=Performance Optimization on Windows Phone 7" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=8099772d-c949-488a-a1d9-d8d1ed410bd7</guid>
      <pubDate>Wed, 28 Jul 2010 22:11:30 +0000</pubDate>
      <category>Framework</category>
      <category>Windows Phone 7</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=8099772d-c949-488a-a1d9-d8d1ed410bd7</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=8099772d-c949-488a-a1d9-d8d1ed410bd7</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/07/28/Performance-Optimization-on-Windows-Phone-7.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=8099772d-c949-488a-a1d9-d8d1ed410bd7</wfw:commentRss>
    </item>
    <item>
      <title>ezyTip Review Published</title>
      <description>&lt;p&gt;&lt;a title="Best Windows Mobile Apps" href="http://www.bestwindowsmobileapps.com/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="logo" border="0" alt="logo" align="right" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipReviewPublished/38E8B962/logo.gif" width="260" height="51" /&gt;&lt;/a&gt;My &lt;a href="http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank"&gt;ezyTip&lt;/a&gt; windows mobile application was just reviewed by &lt;a title="http://www.bestwindowsmobileapps.com/" href="http://www.bestwindowsmobileapps.com/"&gt;Best Windows Mobile Apps&lt;/a&gt; who are an independent reviewer of Windows Mobile Applications and are a great source to find interesting Apps. They gave &lt;a href="http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank"&gt;ezyTip&lt;/a&gt; 4 out of 5 stars and made it the featured App!&amp;#160; The app lost a few points due to some missing features around emailing and uneven splits which is fair. These are features that are planned for the next major version.&lt;/p&gt;  &lt;p&gt;I’ve given them 10 free copies of the App to give away (wasn’t dependant on the outcome of the review btw) so if you want a free copy you’d best be quick and leave a &lt;a href="http://bit.ly/aizv75" target="_blank"&gt;comment&lt;/a&gt; to be eligible. You can find the review &lt;a href="http://bit.ly/aizv75" target="_blank"&gt;here&lt;/a&gt; .&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx&amp;amp;title=ezyTip Review Published" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx&amp;amp;title=ezyTip Review Published" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx&amp;amp;title=ezyTip Review Published" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=93153ee0-b378-4711-b8ed-165433654215</guid>
      <pubDate>Thu, 22 Apr 2010 15:28:56 +0000</pubDate>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=93153ee0-b378-4711-b8ed-165433654215</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=93153ee0-b378-4711-b8ed-165433654215</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/04/22/ezyTip-Review-Published.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=93153ee0-b378-4711-b8ed-165433654215</wfw:commentRss>
    </item>
    <item>
      <title>ezyTip for Windows Mobile Goes Live!!</title>
      <description>&lt;p&gt;Its been awhile since my last post, and during this time I’ve been working on a Windows Mobile Application for the new &lt;a href="https://marketplace.windowsphone.com/Default.aspx" target="_blank"&gt;Windows Mobile Marketplace&lt;/a&gt;. It was an interesting experience, which I think turned out quite well in the end. I thought I’d start with a simple App that wouldn’t take too long, and I considered a number of alternatives. However, Windows Mobile being such a non-standard beast made even simple applications challenging. In the end I settled on a Tip Calculator which sounded very easy to do. Well, this is windows mobile, so &lt;strong&gt;&lt;em&gt;nothing is easy&lt;/em&gt;&lt;/strong&gt; to do!!&lt;a href="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsMobileGoesLive/4D10C8FA/ezyTipScreen.jpg" rel="lightbox[Screens]"&gt;&lt;img style="margin: 10px 0px 10px 10px; display: inline" title="1.6 Aspect Ratio Screen" alt="1.6 Aspect Ratio Screen" align="right" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsMobileGoesLive/1321860E/ezyTipScreen_thumb.jpg" width="144" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One of the key issues with Windows Mobile development is that 90%+ of apps still look like they were built back in the 80s. A quick look at the &lt;a href="https://marketplace.windowsphone.com/Default.aspx" target="_blank"&gt;Windows Mobile Marketplace&lt;/a&gt; will show that this is unfortunately still true. Though some developers are trying to break this trend and make more modern looking Applications.&lt;/p&gt;  &lt;p&gt;So in developing my simple Application I wanted to make it look as good as any application on the iPhone, which is where the challenges really being. Unlike modern mobile platforms, Windows Mobile simply doesn’t make it easy to do modern looking applications. Its &lt;strong&gt;hard!&lt;/strong&gt; which explains why so many Windows Mobile Applications look so bad.&lt;/p&gt;  &lt;p&gt;Fortunately I managed to find the open-source project &lt;a href="http://www.codeplex.com/Wikipage?ProjectName=fluid" target="_blank"&gt;Fluid Controls&lt;/a&gt;, which is a framework for building modern looking UIs on Windows Mobile including gesture support on 6.0/6.1 devices. Its a great framework, but hasn’t been updated in over a year, is still in Beta and has only a sample application to work out how to use it; which takes a bit of time. Also, despite how good the framework is, it didn’t support all my needs so I had to modify the framework quite a bit to fill in all the gaps. Having said that if you’re looking to do modern UI dev work for Windows Mobile you should check that project out.&lt;a href="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsMobileGoesLive/2491E6E6/ezyTipScreen2.jpg" rel="lightbox[Screens]"&gt;&lt;img style="margin: 10px 0px 10px 10px; display: inline" title="1.3 Aspect Ratio" alt="1.3 Aspect Ratio" align="right" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsMobileGoesLive/31F7F9EC/ezyTipScreen2_thumb.jpg" width="180" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So the other challenge as any Windows Mobile developer will know is supporting the crazy number of screen resolutions. The general practice of moving controls around is fine for the older 80s look. However if you’re using an image as a background that doesn’t quite work. As a result I had to create specific artwork for each aspect ratio. The design that was used was to cut off the left and right sides of the 1:1.3 ratio screen to produce the 1:1.6 screen. In the final product, I had native support for 480x640 and 480x800 which are the two high resolutions for the two aspect ratios I supported. If your device has a resolution which is different but of the same aspect ratio (ie 1:1.3 or 1:1.6), then the Application will automatically rescale all the images to fit the resolution. This works really well for the most part, except for those with 240x400, the scaling features of Windows Mobile are not particularly good and it does a terrible job for this resolution. The solution is to provide native images for this resolution, but you also need to consider the size of the download. The final version comes in at 950K so adding more screens would have put it over a 1 Meg. Though I’ve since discovered there are users who use this resolution so I might add an update with the new resolution.&lt;/p&gt;  &lt;p&gt;So it was an enjoyable side project to work on which took considerably longer to do than I expected. However, I think the final result is good and it proves the doing modern applications on Windows Mobile is possible, but not trivial.&lt;/p&gt;  &lt;p&gt;In future posts I’ll run through my experience with the new Windows Mobile Marketplace and whether I’ll be doing any new 6.x development.&lt;/p&gt;  &lt;p&gt;For those with a Windows Mobile Professional phone, you can check out the App with the link below:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a title="ezyTip - Tip Calculator" href="https://marketplace.windowsphone.com/details.aspx?appId=badfbb56-f458-483a-abe8-c86d4b36c5c5" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="marketplace" border="0" alt="marketplace" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ezyTipforWindowsMobileGoesLive/493E9CAC/marketplace.png" width="218" height="70" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Nb: if you are not in the USA, UK or Canada the above link may not work. If so you need to change your catalog (bottom right of website) to either USA, UK or Canada then do a search for ‘ezytip’.&lt;/em&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx&amp;amp;title=ezyTip for Windows Mobile Goes Live!!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx&amp;amp;title=ezyTip for Windows Mobile Goes Live!!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx&amp;amp;title=ezyTip for Windows Mobile Goes Live!!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (GarryMc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=eb35e79e-6b1f-47e7-aeab-d4db7461d06e</guid>
      <pubDate>Thu, 04 Mar 2010 13:44:11 +0000</pubDate>
      <category>Windows Mobile</category>
      <dc:publisher>GarryMc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=eb35e79e-6b1f-47e7-aeab-d4db7461d06e</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=eb35e79e-6b1f-47e7-aeab-d4db7461d06e</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2010/03/04/ezyTip-for-Windows-Mobile-Goes-Live!!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=eb35e79e-6b1f-47e7-aeab-d4db7461d06e</wfw:commentRss>
    </item>
    <item>
      <title>UnitTestEx v1.2 Released!</title>
      <description>&lt;p&gt;I’ve just released an update to the &lt;a href="http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx"&gt;UnitTestEx&lt;/a&gt; component which as the following additions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Re-factored API signatures to make them much simpler &lt;/li&gt;    &lt;li&gt;ExecuteUnitTestScript to support in/out params &lt;/li&gt;    &lt;li&gt;Renamed ExecuteUnitTestValidationScriptReader to ExecuteUnitTestScriptReader which also now supports in params &lt;/li&gt;    &lt;li&gt;Added unit test for all database related features ie ExecuteUnitTestScript &lt;/li&gt;    &lt;li&gt;Added database scripts to allow testing of the new unit tests. &lt;/li&gt;    &lt;li&gt;Compare now supports the ability to treat empty collections as the same as null collections. This feature can be useful if de-serialize your expected results from an XML file and your actual forces some collections to be null but the default behaviour of the code is to have initialized collections. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For anyone who has been using an older version, this version represents a number of breaking changes. The changes however are not significant and the APIs are now quite stable.&lt;/p&gt;  &lt;p&gt;If you haven’t checked out the component yet, take a look at the &lt;a href="http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx"&gt;original post&lt;/a&gt; and the &lt;a title="UnitTestEx Home" href="http://unittestex.codeplex.com/"&gt;code&lt;/a&gt; on CodePlex.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</guid>
      <pubDate>Thu, 20 Aug 2009 23:23:51 +0000</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</wfw:commentRss>
    </item>
    <item>
      <title>Visual Studio Debugging Slow? Try this!</title>
      <description>&lt;p&gt;On my current project I find that I’m working with Visual Studio on a VM that is in an isolated domain, which is making life interesting! One of those ‘interesting’ things was that Debugging in Visual Studio was horrendously slow! It would take several minutes to get to the first break point (first line of a unit test), then still be slow when accessing other parts of the code.&lt;/p&gt;  &lt;p&gt;The slow part of the process was the loading of the symbol files for each of the referenced dlls, including those of the .NET framework. As it turns out Visual Studio actually loads the symbol files for the .NET Framework from the internet! So the delay is primarily due to timeouts which lead to an unbearable (read unusable) debugging environment. The good news is that there is a solution which is quite simple and easy to implement.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Solution&lt;/h1&gt;  &lt;p&gt;In order to dramatically improve your debugging you need to have Visual Studio use a cached version of the symbol files, as well as ensure its not trying to locate symbol files on slow network shares.&lt;/p&gt;  &lt;p&gt;Here are the steps you need to fix the issue:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a directory to store you locally cached symbols. Ie C:\Temp\SymbolCache &lt;/li&gt;    &lt;li&gt;Change the debug settings for loading symbols, via Tools|Options|Debugging|Symbols.      &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/1CC7532C/DebuggingOptions1.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DebuggingOptions1" border="0" alt="DebuggingOptions1" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/69F74CB7/DebuggingOptions1_thumb.png" width="244" height="143" /&gt;&lt;/a&gt; &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;(Option 1) Start debugging the code you want (on a machine that can access the internet; even if its slow) and have it sit on a break point. Then go back to the Symbols settings, where you’ll notice the button Load symbols from Microsoft symbol servers is now active (because that was obvious!). Click the button and you’ll see a popup windows indicating the download of the symbol files. After this is complete you can close out of this window and stop debugging. If you now check your Symbol Cache directory you’ll see you have a load of downloaded symbols (may vary depending on what you’ve referenced).      &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/3B9DC70A/SymbolCache.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SymbolCache" border="0" alt="SymbolCache" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/74487117/SymbolCache_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;(Option 2) If you have already done option 1 and you need to apply this to another machine, such as a team members machine, you can simply copy the files from one machine to the other. &lt;/li&gt;    &lt;li&gt;Depending on your environment you may also have one of two environment variables that need updating. Set either of these environment variables to the same location as the cache created in setup 2. The environment variables to change are _NT_SYMBOL_PATH or _NT_ALT_SYMBOL_PATH. The default setting for these are pointing to the Microsoft Symbols server. You can access the variables either via DOS (set command) or via the Advanced System Properties dialog in Windows.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;One you’ve completed the changes you should see a dramatic improvement in your performance. Remember to check in Step 2 that you don’t have any non-existent paths or UNC paths defined as this will also slow things down.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (GarryMc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=b95828a8-3e2e-4576-9883-94c00ce8b759</guid>
      <pubDate>Thu, 20 Aug 2009 22:08:47 +0000</pubDate>
      <category>Visual Studio</category>
      <dc:publisher>GarryMc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=b95828a8-3e2e-4576-9883-94c00ce8b759</pingback:target>
      <slash:comments>51</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=b95828a8-3e2e-4576-9883-94c00ce8b759</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=b95828a8-3e2e-4576-9883-94c00ce8b759</wfw:commentRss>
    </item>
    <item>
      <title>dnp.Framework code released!</title>
      <description>&lt;p&gt;In an effort to start getting more of the code I’ve been working on out in the public domain, I’ve finally released all the code for the &lt;a title="Framework Home Page" href="http://dotnetprofessional.com/blog/page/dnpFramework.aspx" target="_blank"&gt;dnp.Framework&lt;/a&gt; on &lt;a title="Framework CodePlex Home Page" href="http://www.codeplex.com/dnpFramework" target="_blank"&gt;CodePlex&lt;/a&gt;. While its not all complete, most of the code is quite stable and can be used now!&lt;/p&gt;  &lt;p&gt;Some of the major components that are included in the framework include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;&lt;a href="http://dotnetprofessional.com/blog/page/Database-Explorer-API-Overview.aspx" target="_blank"&gt;Database Explorer API&lt;/a&gt;:&lt;/strong&gt; An object oriented database schema API which is ideal for anyone wanting to do code generation. Its based on the provider pattern, so while it currently only supports SQL Server 2005+ its fairly easy to create a new provider for any system. This is stable enough for production use and has an extensive set of unit tests. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data Provider:&lt;/strong&gt; This is a database agnostic API which is fairly similar to the one in the enterprise library except it doesn’t support datasets and the like. Its also has little overhead. This was designed before the Enterprise Library had a decent model, and it has also been used on mobile devices with the compact framework. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DomainModeller:&lt;/strong&gt; An abstract domain model view of a database schema (extends Database Explorer API). This API is most useful to creating scripts for code generation, where you can concentrate on domain concepts such as base classes, derived classes, namespaces and relationships etc, rather than database concepts. Using this API for code generation can significantly reduce the amount of code typically required. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ServiceModel:&lt;/strong&gt; This project is still under development, but aims to provide the first ‘Model’ that extends the Domain Modeller to define a Service based Application framework. The ServiceModel acts as the abstract API for the final code generation scripts which are currently written using CodeSmith. The scripts currently have good support for the data access layer (repository), service layer (business logic) and entities (using design discussed &lt;a title="Modeling Many to One relationships" href="http://dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank"&gt;here&lt;/a&gt;).  &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are other components that are less substantial but provide useful features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Configuration:&lt;/strong&gt; classes to allow custom sections in config files. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;IO:&lt;/strong&gt; classes to make getting info from resource files easier. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Collections:&lt;/strong&gt; classes that support multi-keyed collections. This is useful when you want to key on a natural or business key which is made up of more than one field. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Reflection:&lt;/strong&gt; classes to help with serialization &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Scripting: &lt;/strong&gt;classes that help with naming such as converting names to plural or singular versions, casing such as pascal, camel and proper. There’s also an expression evaluator that allows evaluating an expression against an object. This is used heavily in the Domain Modeller and ServiceModel config files. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; CookieProtection, MachineKey encoding &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Web:&lt;/strong&gt; SafeLocalStorage, thread wide TimeZone conversions, Web log (IIS) Linq provider &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This framework has taken some time to get this far and while not complete does provide a number of features that are useful today. Over the next few months I’ll blog about some of the features mentioned above to provide a better understanding of how to use them. For now the best way to get a feel for how classes are used is to look at the unit tests for the class. Most of the features have tests which give a good idea of how its used.&lt;/p&gt;  &lt;p&gt;If you’d like to have a particular feature explained in more depth, leave a comment here otherwise I’ll pick the ones I like :)&lt;/p&gt;  &lt;p&gt;Oh and you can find all the code &lt;a title="Framework CodePlex Home Page" href="http://www.codeplex.com/dnpFramework" target="_blank"&gt;here!&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=6bc721b0-0207-4161-a296-7fe811e963fb</guid>
      <pubDate>Thu, 21 May 2009 22:25:05 +0000</pubDate>
      <category>.NET 3.5</category>
      <category>.NET 2.0</category>
      <category>ASP.NET</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=6bc721b0-0207-4161-a296-7fe811e963fb</pingback:target>
      <slash:comments>45</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=6bc721b0-0207-4161-a296-7fe811e963fb</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=6bc721b0-0207-4161-a296-7fe811e963fb</wfw:commentRss>
    </item>
    <item>
      <title>Unit Testing and Test Spy Library Released!</title>
      <description>&lt;p&gt;Its been some time since my last post, so I thought I’d start back with news of a small Unit Testing library I’ve been using with my current client. I developed the library to solve a number of issues I was facing while doing my unit tests. The focus of the library is to provide support for:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Test Spy Pattern:&lt;/strong&gt; a type of of fake that monitors calls and data passed rather than trying to mock the implementation. A discussion of the pattern can be found in the &lt;a href="http://xunitpatterns.com/Test%20Spy.html" target="_blank"&gt;xUnit Patterns&lt;/a&gt; book. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Comparing entities:&lt;/strong&gt; the amount of code generally required to test that an entities properties match those of the expected version can be large and tedious to write. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data access testing:&lt;/strong&gt; while using Fakes and the like is great, you still need to test the code that actually talks to the database. This usually ends up taking a reasonable amount of code to setup and execute, making the test harder to read. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This library provides solutions to the above problems which in my experience has produced cleaner tests that are easier to read and understand. The library comes with a fairly detailed &lt;a title="UnitTestEx User Guide" href="http://unittestex.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27528" target="_blank"&gt;User Guide&lt;/a&gt; so I wont go into the details of how everything works here, however I will provide a quick overview of how the library attempts to solve these issues.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Test Spy pattern:&lt;/strong&gt; adding a single property per method that you want to track to your existing Fake (Test Double) and one or two lines of code to the Fakes method implementation provides the following features:       &lt;ul&gt;       &lt;li&gt;Was called &lt;/li&gt;        &lt;li&gt;Method call count &lt;/li&gt;        &lt;li&gt;Parameters passed in to method (per call) &lt;/li&gt;        &lt;li&gt;Ability to define the data returned from any method of a dependency &lt;/li&gt;        &lt;li&gt;Ability to simulate an exception in a dependency &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Comparing entities:&lt;/strong&gt; given two object graphs you can compare each property in a single line of code using the Compare method. The library also supports the ability to ignore certain properties that tend to always change such as primary keys that are identity fields. The Compare method currently handles the basic value types and strings as well as more complex types such as XmlDocument and DataTable, adding a new complex type is a achievable by simply defining a new Type rule. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data access testing:&lt;/strong&gt; when testing code that affects a database, you need to ensure the database is in a particular state before starting. This can be done via calling a stored procedure or maybe running a database script. The library opts for the second approach and allows you to embed SQL script files which can then be executed with a single line of code. This approach ensures devs always have the latest scripts and dont have to remember to update their local copy of the database. There are a other methods that help with querying the database after executing the code under test too. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The library also provides helper routines around Serialization and IO. You can download the library and its User Guide from the CodePlex project below:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.codeplex.com/UnitTestEx" href="http://www.codeplex.com/UnitTestEx"&gt;http://www.codeplex.com/UnitTestEx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As I find the time I’ll blog about some of the technical aspects of the library such as extending the Compare method it to support new complex data types.&lt;/p&gt;  &lt;p&gt;If you end up using it in your project, please leave a comment or if you have any feature improvements (or bugs) post them to the CodePlex site. &lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=76cd9c6f-9512-4771-8594-1778e4094150</guid>
      <pubDate>Wed, 20 May 2009 21:12:09 +0000</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=76cd9c6f-9512-4771-8594-1778e4094150</pingback:target>
      <slash:comments>10</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=76cd9c6f-9512-4771-8594-1778e4094150</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=76cd9c6f-9512-4771-8594-1778e4094150</wfw:commentRss>
    </item>
    <item>
      <title>Turn multiple rows into a single string in SQL Server</title>
      <description>&lt;p&gt;I recently had the task of creating a report where they wanted one of the columns to list out all the users associated with a given report line item in a single comma separated string. My initial thoughts were, that this would involve some type of cursor or at least a loop of some description, which I'd then have to attach to the main result set. However, it seems there's a very nice little trick you can use that will solve this issue without the use of cursors or loops!&lt;/p&gt; &lt;p&gt;With the use of the COALESCE keyword you can create a list in a single line of SQL (except for declarations). I'll use the AdventureWorks database to demonstrate the technique. Assume&amp;nbsp; you need to get a list of Countries and the regions they contain, in a report similar to the one below: &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/TurnmultiplerowsintoasinglestringinSQLSe_13964/SampleReport_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="366" alt="Sample Report" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/TurnmultiplerowsintoasinglestringinSQLSe_13964/SampleReport_thumb.jpg" width="484" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;To produce a list you can use the following SQL:&lt;/p&gt; &lt;div class="csharpcode-wrapper"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @&lt;span class="kwrd"&gt;result&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;    @&lt;span class="kwrd"&gt;result&lt;/span&gt; = &lt;span class="kwrd"&gt;coalesce&lt;/span&gt;(@&lt;span class="kwrd"&gt;result&lt;/span&gt; + &lt;span class="str"&gt;', '&lt;/span&gt;, &lt;span class="str"&gt;''&lt;/span&gt;) + Name&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;    Person.StateProvince&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt;    Person.StateProvince.CountryRegionCode = @CountryRegionCode&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @&lt;span class="kwrd"&gt;Result&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardb34caa4e125d4601b4c591d944183f72_1328);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardb34caa4e125d4601b4c591d944183f72_1328);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
				&lt;div id="CopyToClipboard_Hidden" style="display:none;"&gt;&lt;/div&gt;
				&lt;div id="CopyToClipboard_FlashContainer"&gt;&lt;/div&gt;
                &lt;script type="text/javascript"&gt;

					function CopyToClipboard_Strip( text ){
						text = text.replace( /&amp;nbsp;/g, ' ' );
						text = text.replace( /&amp;quot;/g, '"' );
						text = text.replace( /&amp;#39;/g, '"' );
						text = text.replace( /&amp;amp;/g, '&amp;' );
						text = text.replace( /&amp;lt;/g, String.fromCharCode(60) );
						text = text.replace( /&amp;gt;/g, String.fromCharCode(62) );
						return text;
					}

                    function CopyToClipboard_Copy( text ){

						//### get reference to utility div
						var ele = document.getElementById('CopyToClipboard_Hidden');

						//### the following taken from: http://webchicanery.com/2006/11/14/clipboard-copy-javascript/
						if (false &amp;&amp; window.clipboardData) {
							window.clipboardData.setData( "Text", text );
						} else {
							document.getElementById('CopyToClipboard_FlashContainer').innerHTML = '';
							var divinfo = '&lt;embed id="CopyToClipboard_FlashFile" src="/blog/_clipboard.swf" FlashVars="clipboard=' + encodeURIComponent(text) + '" width="0" height="0" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;';
							document.getElementById('CopyToClipboard_FlashContainer').innerHTML = divinfo;
						}

                    }

					function CopyToClipboard_ViewPlain( text ){
						var win = window.open( '', 'CopyToClipboard_Window', 'width=480, height=480, toolbar=no, menubar=no, scrollbars=auto, resizable=yes, location=no, directories=no, status=no' );
						win.document.write( '&lt;html&gt;&lt;head&gt;&lt;title&gt;Code&lt;/title&gt;&lt;body style="margin:0;padding:0;"&gt;&lt;textarea style="width:100%;height:100%;border:0;"&gt;' + text + '&lt;/textarea&gt;&lt;/body&gt;&lt;/html&gt;' );
					}

                &lt;/script&gt;
            
					&lt;script type="text/javascript"&gt;
						var copyToClipboardb34caa4e125d4601b4c591d944183f72_1328 = CopyToClipboard_Strip('DECLARE @result varchar(max) SELECT    @result = coalesce(@result + \', \', \'\') + NameFROM    Person.StateProvinceWHERE    Person.StateProvince.CountryRegionCode = @CountryRegionCode RETURN @Result');
					&lt;/script&gt;
&lt;p&gt;The way this works is the COALESCE function returns the first non-null expression. For the first record this would be the empty string + Name as @Result would be null. However, the interesting thing is that because we keep concatinating to @Result a single value is returned from the whole result set. The only issue is that for this to work we need a variable to keep storing the information in. So if you want to apply this against another table that supplies the filter, you'll have to create a function that returns the string. As this is a scalar function (ie doesn't return a result set) its use within another query is extremely easy. Assuming a function for the above is called dbo.fnRegionsToString we are left with:&lt;/p&gt;
&lt;div class="csharpcode-wrapper"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; Country, dbo.fnRegionsToString(CountryRegionCode) States&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;
         Person.CountryRegion&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardb34caa4e125d4601b4c591d944183f72_5382);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardb34caa4e125d4601b4c591d944183f72_5382);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardb34caa4e125d4601b4c591d944183f72_5382 = CopyToClipboard_Strip('SELECT Name AS Country, dbo.fnRegionsToString(CountryRegionCode) StatesFROM\r\n         Person.CountryRegion');
					&lt;/script&gt;
&lt;p&gt;The whole script which you can test against the AdventureWorks database is:&lt;/p&gt;
&lt;div class="csharpcode-wrapper"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;IF&lt;/span&gt;  &lt;span class="kwrd"&gt;EXISTS&lt;/span&gt; (&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; dbo.sysobjects &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; [id] = OBJECT_ID(N&lt;span class="str"&gt;'[dbo].[fnRegionsToString]'&lt;/span&gt;) &lt;span class="kwrd"&gt;AND&lt;/span&gt; type &lt;span class="kwrd"&gt;in&lt;/span&gt; (N&lt;span class="str"&gt;'FN'&lt;/span&gt;, N&lt;span class="str"&gt;'IF'&lt;/span&gt;, N&lt;span class="str"&gt;'TF'&lt;/span&gt;, N&lt;span class="str"&gt;'FS'&lt;/span&gt;, N&lt;span class="str"&gt;'FT'&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;DROP&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; dbo.fnRegionsToString&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;GO&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; dbo.fnRegionsToString&lt;/pre&gt;&lt;pre class="alteven"&gt;(&lt;/pre&gt;&lt;pre class="alt"&gt;    @CountryRegionCode &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(5)&lt;/pre&gt;&lt;pre class="alteven"&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;RETURNS&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;Max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;AS&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @&lt;span class="kwrd"&gt;result&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;SELECT&lt;/span&gt;    @&lt;span class="kwrd"&gt;result&lt;/span&gt; = &lt;span class="kwrd"&gt;coalesce&lt;/span&gt;(@&lt;span class="kwrd"&gt;result&lt;/span&gt; + &lt;span class="str"&gt;', '&lt;/span&gt;, &lt;span class="str"&gt;''&lt;/span&gt;) + Name&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;FROM&lt;/span&gt;    Person.StateProvince&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;WHERE&lt;/span&gt;    Person.StateProvince.CountryRegionCode = @CountryRegionCode&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @&lt;span class="kwrd"&gt;Result&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;END&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;GO&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; Country, dbo.fnRegionsToString(CountryRegionCode) States&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;         Person.CountryRegion&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardb34caa4e125d4601b4c591d944183f72_6357);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardb34caa4e125d4601b4c591d944183f72_6357);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardb34caa4e125d4601b4c591d944183f72_6357 = CopyToClipboard_Strip('IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE [id] = OBJECT_ID(N\'[dbo].[fnRegionsToString]\') AND type in (N\'FN\', N\'IF\', N\'TF\', N\'FS\', N\'FT\'))    DROP FUNCTION dbo.fnRegionsToStringGO CREATE FUNCTION dbo.fnRegionsToString(    @CountryRegionCode varchar(5))RETURNS varchar(Max)ASBEGIN     DECLARE @result varchar(max)     SELECT    @result = coalesce(@result + \', \', \'\') + Name    FROM    Person.StateProvince    WHERE    Person.StateProvince.CountryRegionCode = @CountryRegionCode        RETURN @ResultENDGO SELECT Name AS Country, dbo.fnRegionsToString(CountryRegionCode) StatesFROM         Person.CountryRegion');
					&lt;/script&gt;
&lt;p&gt;This makes for a very clean solution to an otherwise painful problem. So the next time you need to turn a lot of records into a single one, check to see if this technique can help.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</guid>
      <pubDate>Fri, 27 Jun 2008 22:56:56 +0000</pubDate>
      <category>SQL</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</pingback:target>
      <slash:comments>35</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</wfw:commentRss>
    </item>
    <item>
      <title>Modeling many-to-one (M:1) entity relationships Part II</title>
      <description>&lt;p&gt;This is the second part of the series which discusses the issues around modeling M:1 (many-to-one) relationships. If you've not read the first part, then its advisable that you read that first before continuing with this part. To keep up to date with this and other blog's you might consider registering with the &lt;a title="The dotNetProfessional RSS feed." href="http://www.dotnetprofessional.com/blog/syndication.axd"&gt;RSS feed&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/post/2008/06/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx"&gt;Part I: The Problem&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part III: BusinessKey as a value type&lt;/p&gt; &lt;h2&gt;Suggested Solution&lt;/h2&gt; &lt;p&gt;Having covered the issues with M:1 relationships and the three different types I'll now present a potential solution which provides the necessary foreign key information, but in a more domain model fashion. I'll also point out yet another issue with the original logical model when it comes to actually using it, which I'll also offer up a solution for. &lt;/p&gt; &lt;p&gt;Remembering the tree types of M:1 relationships discussed previously, lets see how we can treat them differently:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Reference: &lt;/strong&gt;As a reference table will typically (should only have one significant column; which must be unique!) only have one column which we can map to as a string just like we did in the logical model. The effect is that instead of having OrderTypeID we have OrderTypeName, both values are unique and therefore provide a 'key' to the OrderType table. As there's nothing else of real interest in the OrderType table, returning only a single field and merging it into the main entity poses little issue but does provide a much more meaningful value than some arbitrary key. In many cases this can avoid a second call to a service or database as we already have the pertinent information.  &lt;li&gt;&lt;strong&gt;Enum:&lt;/strong&gt; An enum table is also much like the reference table, the only difference being that we can also record all the known values as an enum and tie this enum to the entity exactly like we did in the logical model. When saving the data however, we don't attempt to save the enums number value but its name. That is we send &lt;em&gt;Processing&lt;/em&gt; not &lt;em&gt;1&lt;/em&gt;, as the number may have little connection to the back end database, and again we want to remove our system keys as much as possible. Therefore the save is exactly the same as it would be for a reference type, we just represent the 'string' value differently as we know what the allowable ones are.  &lt;li&gt;&lt;strong&gt;Entity:&lt;/strong&gt; The entity type is the most interesting of the types. If you look at the original model vs the one produced by Linq to SQL, you might be thinking, well its basically the same what's wrong with that? Well a few things actually which is the topic of the next section.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Modeling M:1 Entities&lt;/h3&gt; &lt;p&gt;As suggested, modeling reference and enum types are fairly straightforward just requiring an extra join to get the necessary information (which is worth it as the information is useful!). However, I've indicated that the seemingly correct entity M:1 has some issues. The issues I see are:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The parent entity still has the child key which is a system key, and is most likely useless to a business person.  &lt;li&gt;If you've adopted the Linq to SQL pattern you have the same issues as already discussed with sync issues etc.  &lt;li&gt;If you want to create a new child entity and associate it to the parent you either have to create the entity first (thereby getting its key) or using the Linq to SQL model and attach a new child entity object; which should work fairly well.  &lt;li&gt;Alternative designs may remove the foreign key from the parent and rely on the child telling the parent what the key is. The issue with this is that you must have a full entity as the child even if you are only concerned with the parent. Also adding the association requires the full entity which may not be available at the time of creating a new entity.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In the past I've tended to treat entity M:1 relationships as reference relationship types with a single key from the entity being used as its business key. This works fairly well, that is until you get an entity that has a business key that maps to more than a single column, which unfortunately happens quite often. In these occasions, I tended to use the entities GUID if it has one or revert to the system key (hey I need something!). As I didn't want the burden of having to retrieve an entire entity just so I know the keys.&lt;/p&gt; &lt;p&gt;So while having the entire entity would be nice and does better represent our original model it poses a number of limitations especially if you just want to associate a pre-existing child entity to a parent. What would be good is to have just the keys, but then be able to upscale to the full entity when the use case requires it. This is exactly what I propose as the solution to this issue. Instead of having a single value to represent a complex entities M:1 relationship we have what I'm calling a business key entity which only knows about the &lt;strong&gt;unique&lt;/strong&gt; business key for that entity and it acts like a value type. The parent then has a relationship with this business key entity not the full entity. Initially I thought an interface could be used to avoid having a separate business entity but as it turns out you can't serialize a property that has an interface as its return type. That basically means in order to support polymorphism (ie the ability to upscale) we have to use implementation inheritance. The original model is demonstrated below using this new technique:&lt;/p&gt; &lt;p&gt;&lt;a title="Model using suggested approach" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_A15E/Model_2.jpg" rel="lightbox"&gt;&lt;img height="210" alt="Model using suggested approach" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_A15E/Model_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;For those who prefer to look at code rather than diagrams, here's how the class for the OrderDetail class and Product business key classes look. The other classes follow a similar pattern, if you are keen to see how all the code looks, leave an email and I'll try bundle it all up:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="csharpcode-wrapper"&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; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OrderDetailBusinessKey &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Int32 _orderDetailID;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;     &lt;span class="rem"&gt;//  Business key constructor&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetailBusinessKey(System.Int32 orderDetailID)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;         _orderDetailID = orderDetailID;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetailBusinessKey(){}&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Int32 OrderDetailID&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;         get {&lt;span class="kwrd"&gt;return&lt;/span&gt; _orderDetailID;}&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;         set {_orderDetailID = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&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; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt; [Serializable]&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OrderDetail&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;     : OrderDetailBusinessKey&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Private Variables&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; OrderBusinessKey _order;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; ProductBusinessKey _product;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Int32 _quantity;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Decimal _price;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Decimal _total;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;     &lt;span class="rem"&gt;// Variables for relationships&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Constructors&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetail()&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;         &lt;span class="kwrd"&gt;this&lt;/span&gt;.Initialize();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  38:&lt;/span&gt;     &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:&lt;/span&gt;     &lt;span class="rem"&gt;/// This code initializes the domain value types for the generated properties&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  40:&lt;/span&gt;     &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:&lt;/span&gt;     &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  42:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:&lt;/span&gt;         _order = &lt;span class="kwrd"&gt;new&lt;/span&gt; bl.OrderBusinessKey();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  44:&lt;/span&gt;         _product = &lt;span class="kwrd"&gt;new&lt;/span&gt; bl.ProductBusinessKey();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  46:&lt;/span&gt;         &lt;span class="rem"&gt;// Call the Initialize routine in the partial class&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:&lt;/span&gt;         &lt;span class="kwrd"&gt;this&lt;/span&gt;.ExtendedInitialize();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  48:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  50:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Public Properties&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  52:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  54:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderBusinessKey Order&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  56:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _order; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:&lt;/span&gt;         set { _order = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  58:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  60:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey Product&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  62:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _product; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:&lt;/span&gt;         set { _product = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  64:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  66:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Int32 Quantity&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  68:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _quantity; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:&lt;/span&gt;         set { _quantity = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  70:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  72:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Decimal Price&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  74:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _price; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  75:&lt;/span&gt;         set { _price = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  76:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  77:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  78:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Decimal Total&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  79:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  80:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _total; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  81:&lt;/span&gt;         set { _total = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  82:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  83:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  84:&lt;/span&gt; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  85:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  86:&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ProductBusinessKey &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  87:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  88:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.String _productName;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  89:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  90:&lt;/span&gt;     &lt;span class="rem"&gt;//  Business key constructor&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  91:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey(System.String productName)&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  92:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  93:&lt;/span&gt;         _productName = productName;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  94:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  95:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey(){}&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  96:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  97:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.String ProductName&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  98:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  99:&lt;/span&gt;         get {&lt;span class="kwrd"&gt;return&lt;/span&gt; _productName;}&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt; 100:&lt;/span&gt;         set {_productName = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 101:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt; 102:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardefb00cf201eb4a48ad038680ad86335d_6356);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardefb00cf201eb4a48ad038680ad86335d_6356);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardefb00cf201eb4a48ad038680ad86335d_6356 = CopyToClipboard_Strip('public partial class OrderDetailBusinessKey    2: {   3:     private System.Int32 _orderDetailID;   4:     5:     //  Business key constructor   6:     public OrderDetailBusinessKey(System.Int32 orderDetailID)   7:     {   8:         _orderDetailID = orderDetailID;   9:     }  10:     public OrderDetailBusinessKey(){}  11:    12:     public System.Int32 OrderDetailID  13:     {  14:         get {return _orderDetailID;}  15:         set {_orderDetailID = value; }  16:     }  17: }  18:    19: [Serializable]  20: public partial class OrderDetail  21:     : OrderDetailBusinessKey  22: {  23:     #region Private Variables  24:     private OrderBusinessKey _order;  25:     private ProductBusinessKey _product;  26:     private System.Int32 _quantity;  27:     private System.Decimal _price;  28:     private System.Decimal _total;  29:     // Variables for relationships  30:     #endregion  31:    32:     #region Constructors  33:     public OrderDetail()  34:     {  35:         this.Initialize();  36:     }  37:    38:     /// &amp;lt;summary&amp;gt;  39:     /// This code initializes the domain value types for the generated properties  40:     /// &amp;lt;/summary&amp;gt;  41:     protected virtual void Initialize()  42:     {  43:         _order = new bl.OrderBusinessKey();  44:         _product = new bl.ProductBusinessKey();  45:    46:         // Call the Initialize routine in the partial class  47:         this.ExtendedInitialize();  48:     }  49:     #endregion  50:    51:     #region Public Properties  52:    53:    54:     public OrderBusinessKey Order  55:     {  56:         get { return _order; }  57:         set { _order = value; }  58:     }  59:    60:     public ProductBusinessKey Product  61:     {  62:         get { return _product; }  63:         set { _product = value; }  64:     }  65:    66:     public System.Int32 Quantity  67:     {  68:         get { return _quantity; }  69:         set { _quantity = value; }  70:     }  71:    72:     public System.Decimal Price  73:     {  74:         get { return _price; }  75:         set { _price = value; }  76:     }  77:    78:     public System.Decimal Total  79:     {  80:         get { return _total; }  81:         set { _total = value; }  82:     }  83:     #endregion  84: }  85:    86: public partial class ProductBusinessKey   87: {  88:     private System.String _productName;  89:    90:     //  Business key constructor  91:     public ProductBusinessKey(System.String productName)  92:     {  93:         _productName = productName;  94:     }  95:     public ProductBusinessKey(){}  96:    97:     public System.String ProductName  98:     {  99:         get {return _productName;} 100:         set {_productName = value; } 101:     } 102: }');
					&lt;/script&gt;
&lt;p&gt;At first glance this might seem overly complex, but if you think about what's happening its not. The perceived complexity comes from the fact that every 'entity' now has a base business key class. While I've shown them all on the diagram, in general they wouldn't need to be seen, just knowing that the property is type ProductBusinessKey would be enough without actually showing the relationship. However, looking at the model, we can see that all but the primary key IDs have been eliminated from our domain model and it looks surprisingly similar to what our original logical model looked like. This approach provides a number of benefits despite its slightly more complex model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible persistence:&lt;/strong&gt; You can add either an existing entity to a parent via its business key or the entire entity. The code used to persist the relationship can simply check what its type is to determine if a full entity needs updating/saving or just an association is required based on the business key. Also you don't have the duplication of keys, so you can write Order.Status = Status.Shipped or even OrderDetail.Product.ProductName = "Product B" (assuming you are using the BusinessKey not the full entity) which seems very intuitive. 
&lt;li&gt;&lt;strong&gt;Eliminate foreign key IDs:&lt;/strong&gt; Although its true that some entities don't have business or natural keys. In these situations, you're left with either using a GUID if available or the system primary key. 
&lt;li&gt;&lt;strong&gt;Entities are more useful:&lt;/strong&gt; Your entities now having gotten rid of meaningless keys (from the business perspective) can do more without requesting more data from the server. Ie if you wanted to list the OrderDetails chances are you could get away with displaying OrderDetail.Product.ProductName to the user and not have to worry about retrieving more detail about a product unless specifically requested. 
&lt;li&gt;&lt;strong&gt;SOA friendly:&lt;/strong&gt; This design is more friendly as the entities resemble documents more than they represent a table, as such they make for a much friendlier XML representation which is now human readable ie instead of seeing IDs for products you'll see the actual product names.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So what's the downside of the approach? From what I can see the main downside is the amount of effort required to make it all work. There are a lot more classes that need creating and you do have to do some extra joins in your selects too; however I believe it reduces complexity overall as the model is more natural and cleaner to work with. However, these issues can be mitigated via code generation, and the good news is that I'll be releasing something fairly soon (notice the vague reference) that implements this model. The sample above was completely code generated. If anyone is interested in being an alpha/beta tester, send me an email via the contacts page or leave a comment.&lt;/p&gt;
&lt;p&gt;While this might look like the end of the discussion, there are still a few things that need addressing including inheritance and the concept of the business key as a value type. These will be covered in the last part of this series, so check back soon.&lt;/p&gt;
&lt;p&gt;This discussion is to obtain feedback on how others feel about the approach I'm taking with my models and open a discussion on how best to model these M:1 relationships. I look forward to any feedback, positive or negative on the approach.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</guid>
      <pubDate>Wed, 25 Jun 2008 19:00:13 +0000</pubDate>
      <category>.NET 2.0</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</pingback:target>
      <slash:comments>8</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</wfw:commentRss>
    </item>
    <item>
      <title>Modeling many-to-one (M:1) entity relationships Part I</title>
      <description>&lt;p&gt;Designing a domain model can be a tough job and if you're lucky enough to start from scratch then it becomes even tougher once you apply it to the physical database model. Over the next few posts I' like to discuss the issues we encounter when modeling this relationship type, examine the way its 'normally' done and then present an alternative that I believe presents a more domain model centric view of the world. The series will be broken up into the following sections, with this being the first. To keep up to date with this and other blog's you might consider registering with the &lt;a title="The dotNetProfessional RSS feed." href="http://www.dotnetprofessional.com/blog/syndication.axd"&gt;RSS feed&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Part I: The Problem&lt;/p&gt; &lt;p&gt;&lt;a title="Part II: Suggested Solution" href="http://www.dotnetprofessional.com/blog/post/2008/06/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx"&gt;Part II: Suggested Solution&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part III: BusinessKey as a value type&lt;/p&gt; &lt;p&gt;The main issue when designing a domain model is that they don't have these oddities called foreign keys, as the relationships are known by association. However, once you turn your domain model into a database schema we have to start adding all these extra keys, which get worse when you have a M:M (many-to-many) relationship! In this post I'd like to discuss how we normally model the M:1 (many-to-one) relationship and its pitfalls. &lt;/p&gt; &lt;h2&gt;The Problem&lt;/h2&gt; &lt;p&gt;When designing a domain model (entity model) in UML its unlikely that you'd include foreign key relationships as part of your design as this is a database concept rather than a domain concept. If we take a very simple and arguably contrived example (its very basic just to highlight the concepts I want to discuss) of an Order it might look something like this (note I'm using the VS class designer which doesn't support multiplicities hence I have to use two associations to highlight relationships):&lt;/p&gt; &lt;p&gt;&lt;a title="Logical Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/LogicalModel_2.jpg" rel="lightbox"&gt;&lt;img height="244" alt="Logica Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/LogicalModel_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In this example we have three different types of M:1 relationships being modeled, which are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Entity &lt;/strong&gt;- The OrderDetail --&amp;gt; Product and Oder--&amp;gt;Customer are M:1 relationships which map to other entities within the business domain.  &lt;li&gt;&lt;strong&gt;Reference &lt;/strong&gt;- The Order.OrderType property is one that is restricted by a known set of values. However, this set of values can change over the life time of the application. That is its data driven and so the current values can't be coded directly within the application. Also a reference value is usually defined as a single field with no other business properties.  &lt;li&gt;&lt;strong&gt;Enum&lt;/strong&gt; - The Order.Status property is also restricted by a known set of values. However, unlike a reference type the values don't or can't change. These values typically drive logic which is set during design, adding a new value after deployment wouldn't add value as the application wouldn't know what to do with it. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Now that I've defined the different M:1 relationship types, they would typically be modeled in the database all the same way as foreign key constraints to their respective tables. The following diagram shows the ER (Entity Relationship) diagram of the physical database model.&lt;/p&gt; &lt;p&gt;&lt;a title="Physical Database Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/PhysicalModel_2.jpg" rel="lightbox"&gt;&lt;img height="251" alt="Physical Database Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/PhysicalModel_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;So the next step in modeling our sample is to create the actual business entities that we can use in a real application, taking into account how our data is physically stored so that we can map our logical to the physical as easy as possible. This of course is where things typically start to deviate from our nice logical model. We have to take these foreign keys into consideration as the database needs them, so typically we end up with something more like the following figure than our original logical model. The following was created using Linq for SQL, which like most O/RMs (the Entity Framework will improve on this) will create something like the following:&lt;/p&gt; &lt;p&gt;&lt;a title="Linq to SQL Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/Linq-Model_2.jpg" rel="lightbox"&gt;&lt;img height="341" alt="Linq to SQL Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/Linq-Model_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;You'll notice from this model that it more resembles the database model than it does our original logical model. We have an extra entity in the OrderType which we'd probably have in our logical too, to allow for maintenance but we didn't need to tie this object to our Order entity. The changes that were made to our original model can be summarized as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Simple types are now complex types, namely instead of a simple enum or string we now have full entities with their associated complexities.  &lt;li&gt;Our 'domain' entities now have system keys liberally scattered throughout to support persistence back to the database. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We also have the following issues as a result of this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;We expose a lot of internal information about our database when we expose foreign keys, exposing this data presents a security risk as a hacker may attempt to corrupt your data by altering the primary or foreign keys. This becomes a bigger issue when you expose your data via web services.&amp;nbsp; &lt;li&gt;In the case of Linq to SQL we also have duplication of foreign key fields, namely we have both an OrderTypeID (foreign key field) and an object reference to the OrderType entity. This just looks plain ugly! Also lets say you want to change the OrderType to a different one, if you change the OrderTypeID from 1 to 2, and you did have an OrderType entity associated at the time, you'd be out of sync! The entity version of the OrderType wouldn't match the change you've just made. In the Linq to SQL architecture you're not even allowed to change the foreign key once its been set! You have to change the OrderType entity which will then update the Order.OrderTypeID. Which only goes to highlight the problems. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So now that I've expressed the issue and the potential problems with this type of design which is an all to common pattern, with the exception of the double foreign key reference that Linq to SQL uses . The question becomes why? The reasons as I see it are two fold:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Effort, it takes some effort to design more closely to the original logical model  &lt;li&gt;Architectural/Technical in that we need those damn keys, so the issue is how do we make a nicer model without loosing the essential information we need? &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The next part of the series will examine what we can do to fix this situation and bring our model back in line with what we originally intended.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</guid>
      <pubDate>Sun, 22 Jun 2008 13:06:18 +0000</pubDate>
      <category>.NET 2.0</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</pingback:target>
      <slash:comments>49</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=df81b12d-6a6c-48a9-b568-e67a5869d93e</wfw:commentRss>
    </item>
    <item>
      <title>Create a full entity class diagram with a T4 template</title>
      <description>&lt;p&gt;I've just released another sample for the Database Explorer API, this time using the built in features of Visual Studio 2008 (should work with VS 2005 with a download of the SDK). Visual Studio 2008 comes with a built in code generator known as T4. While the built in editing experience leaves a bit to be desired the free &lt;a href="http://www.t4editor.net/" target="_blank"&gt;T4 editor&lt;/a&gt; by Clarius Consulting goes a long way to making it workable. If you download the editor, it indicates that the time bomb expires in Jan 1, 2008; this however isn't the case as they're still working on the next release.&lt;/p&gt; &lt;p&gt;This sample creates a fairly decent (not perfect by any means) set of entities which you can then easily drop on to a class designer and get a good feel for how your domain model looks. It has support for all but the recursive relationship type, which could be added as the API does support this. This sample is provided to show how much you can do with both T4 and the API in only a small amout of code. I've included a screen shot from the Adventure Works sample, which as you can see supports many relationship types. The sample download includes the results run against the AdventureWorks sample database.&lt;/p&gt; &lt;p&gt;To download the new sample visit the projects &lt;a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=dnpFramework&amp;amp;ReleaseId=11811" target="_blank"&gt;CodePlex page&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Remember to provide as much feed back on the samples and API as you can. Enjoy!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/CreateafullentityclassdiagramwithaT4temp_13FDE/Entity%20Model_2.png" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="134" alt="Entity Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/CreateafullentityclassdiagramwithaT4temp_13FDE/Entity%20Model_thumb.png" width="244" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;</description>
      <link>http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx#comment</comments>
      <guid>http://www.dotnetprofessional.com/blog/post.aspx?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</guid>
      <pubDate>Wed, 26 Mar 2008 05:42:02 +0000</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <category>Visual Studio</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</pingback:target>
      <slash:comments>16</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</wfw:commentRss>
    </item>
  </channel>
</rss>