<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  >

<channel>
  <title>CodeGear TeamB Blogs Master Site Feed</title>
  <link>http://blogs.teamb.com/feeds</link>
  <description>Shows all posts, comments, and pages from all blogs on this WPMU powered site</description>
  <pubDate>Fri, 13 Aug 2010 16:14:09 +0000</pubDate>
  <generator>http://wordpress.org/?v=2.6.2</generator>
  <language>en</language>
  <item>
    <title>Troubleshooting Entity Framework Connection Strings</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/08/13/38628/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/08/13/38628/#comments</comments>
    <pubDate>Fri, 13 Aug 2010 16:14:09 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38628</guid>
    <description><![CDATA[In an application which uses the Entity Framework, you may see the following error at runtime:
MetadataException: Unable to load the specified metadata resource
The cause of this error is a missing or malformed Entity Framework connection string. In particular, the cause of this error is the metadata parameter of the connection string. Let&#8217;s examine this more closely.
Which Config File?
Before [...]]]></description>
      <content:encoded><![CDATA[<p>In an application which uses the Entity Framework, you may see the following error at runtime:</p>
<blockquote><p>MetadataException: Unable to load the specified metadata resource</p></blockquote>
<p>The cause of this error is a missing or malformed Entity Framework connection string. In particular, the cause of this error is the <code>metadata</code> parameter of the connection string. Let&#8217;s examine this more closely.</p>
<h3>Which Config File?</h3>
<p>Before you begin troubleshooting, make sure you are looking at the correct file.</p>
<p>Connection strings are loaded from the configuration file for the <em>executing</em> assembly, which may not be the assembly which contains your Entity Framework model. So if you have a data assembly containing an Entity Framework model and a web assembly containing a web application which references the data assembly, then the Entity Framework connection string needs to be in the <code>Web.config</code> file for the web assembly. The data assembly can have its own connection string, if you like (this is convenient, as it will be used by the Entity Framework designer), but it will not be used by the web application at runtime.</p>
<h3>Metadata</h3>
<p><a href="http://msdn.microsoft.com/en-us/library/cc716756.aspx">MSDN documents EF connection strings generally</a>. But the cause of the error above is specifically the <code>metadata</code> parameter. This parameter tells the Entity Framework where to find your EDMX at runtime. When your application is compiled, the EDMX is split into three parts: CSDL, MSL, and SSDL. For the purposes of this post, you don&#8217;t need to think about what they mean right now; it&#8217;s enough to know that you need all three of them at runtime.</p>
<p>The EDMX can be supplied to the application as embedded resources or files on disk. The default is embedded resources, so we&#8217;ll focus on that case.</p>
<p>The <code>metadata</code> parameter for an application with an Entity Framework model called <code>Model.edmx</code> in an assembly called <code>Simple Mvc.Data.dll</code> might look like this:</p>
<blockquote>
<pre><span>&lt;</span><span>connectionStrings</span><span>&gt;</span>
<span>	&lt;</span><span>add</span><span> </span><span>name</span><span>=</span>"<span>MyEntities</span>"<span> </span><span>connectionString</span><span>=</span>"<span>metadata=
            res://Simple Mvc.Data.dll/Model.csdl|
            res://Simple Mvc.Data.dll/Model.ssdl|
            res://Simple Mvc.Data.dll/Model.msl;provider= &lt;!-- ... --&gt;</span></pre>
</blockquote>
<p>So you can see there is one reference for each of the three parts of the EDMX that we need at runtime. They all work in the same way, so let&#8217;s examine just the first more closely. The CSDL reference looks like this:</p>
<pre><span>            res://Simple Mvc.Data.dll/Model.csdl</span></pre>
<p>It specifies three things:</p>
<ol>
<li>We&#8217;re loading the CSDL from a resource. That&#8217;s the "<code>res://</code>" part.</li>
<li>The name of the assembly which contains the resource, "<code>Simple Mvc.Data.dll</code>". If your assembly is strong named, you can specify a strong name, in all its verbose glory, here.</li>
<li>The name of the resource itself, "<code>Model.csdl</code>". <em>Do not confuse this with the EDMX or model name</em>. In this case they happen to be the same, except for the extension, but <em>that&#8217;s not always true!</em></li>
</ol>
<p>Let&#8217;s examine #2 and 3 more closely.</p>
<h4>Assembly name</h4>
<p>It&#8217;s really common to omit the assembly name in a connect string, and use <code>*</code> instead, like this:</p>
<blockquote>
<pre><span>&lt;</span><span>connectionStrings</span><span>&gt;</span>
<span>	&lt;</span><span>add</span><span> </span><span>name</span><span>=</span>"<span>MyEntities</span>"<span> </span><span>connectionString</span><span>=</span>"<span>metadata=
            res://*/Model.csdl|
            res://*/Model.ssdl|
            res://*/Model.msl;provider= &lt;!-- ... --&gt;</span></pre>
</blockquote>
<p>This means that instead of loading the resource from one specific assembly, the EF will scan all loaded assemblies at runtime. Two obvious downsides to this are that it takes a bit of time to do this, and the assembly might not be loaded yet. The second case is one reason you might get the error at the start of this post. So specifying the assembly explicitly is always a good idea, I think.</p>
<h4>Resource names</h4>
<p>Remember how I said that the resource name isn&#8217;t necessarily the same as the model name? Here&#8217;s a real-life example of that. I opened one of our production assemblies in Reflector, and found this:</p>
<p><a href="/files/2010/08/vertexefresources_2751.png"><img src="/files/2010/08/vertexefresources_2751.png" alt="" width="304" height="123" /></a></p>
<p>There&#8217;s actually a good reason that those resources have such bizarre names, but it&#8217;s a digression and not relevant to this post. The point is that after you&#8217;re sure the assembly name is right, the next step in solving the error at the top of this post is to double-check the resource names.</p>
<p>A simpler resource name will look like this:</p>
<p><a href="/files/2010/08/efresources_2749.png"><img src="/files/2010/08/efresources_2749.png" alt="" width="173" height="110" /></a></p>
<p>Remember the "simpler" <code>metadata</code> where I used <code>*</code> instead of the assembly name? You can go even simpler. This metadata, perhaps surprisingly, actually works (with caveats):</p>
<blockquote>
<pre><span>&lt;</span><span>connectionStrings</span><span>&gt;</span>
<span>	&lt;</span><span>add</span><span> </span><span>name</span><span>=</span>"<span>MyEntities</span>"<span> </span><span>connectionString</span><span>=</span>"<span>metadata=
            res://*/;provider= &lt;!-- ... --&gt;</span></pre>
</blockquote>
<p>This is the "throw everything against the wall and see what sticks" approach to a connect string. It will probably fail if your resources don&#8217;t happen to have the same name as your model, or if the assembly doesn&#8217;t happen to be loaded. But it (in simpler cases, anyway) frees the programmer from having to think about what any of this stuff <em>means</em>, so it&#8217;s a popular solution.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38628&amp;akst_action=share-this" onclick="akst_share('38628', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F08%2F13%2F38628%2F', 'Troubleshooting+Entity+Framework+Connection+Strings'); return false;" title="Post to del.icio.us, etc." id="akst_link_38628" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Troubleshooting%20Entity%20Framework%20Connection%20Strings&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F08%2F13%2F38628%2F" id="akst_email_38628" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>New InterBase Partner DVD In Progress</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/08/12/38626/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/08/12/38626/#comments</comments>
    <pubDate>Thu, 12 Aug 2010 20:59:41 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38626</guid>
    <description><![CDATA[The next version of InterBase is nearing completion, and, as always, will include a Partner DVD with demo versions of third-party tools supporting InterBase. If you are an InterBase Partner, you should have already been notified of how to submit your product.
If you produce a tool or component supporting InterBase and have not already received [...]]]></description>
      <content:encoded><![CDATA[<p><a href="http://www.embarcadero.com/datarage2/sessions">The next version of InterBase</a> is nearing completion, and, as always, will include a Partner DVD with demo versions of third-party tools supporting InterBase. If you are an InterBase Partner, you should have already been notified of how to submit your product.</p>
<p>If you produce a tool or component supporting InterBase and have not already received a notice about the Partner DVD, then please contact Anders Ohlsson (firstname.lastname@embarcadero.com) immediately.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38626&amp;akst_action=share-this" onclick="akst_share('38626', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F08%2F12%2F38626%2F', 'New+InterBase+Partner+DVD+In+Progress'); return false;" title="Post to del.icio.us, etc." id="akst_link_38626" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=New%20InterBase%20Partner%20DVD%20In%20Progress&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F08%2F12%2F38626%2F" id="akst_email_38626" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>grid.history Demo Fixed</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/07/19/38624/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/07/19/38624/#comments</comments>
    <pubDate>Mon, 19 Jul 2010 13:50:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38624</guid>
    <description><![CDATA[Apologies to those who tried my grid.history demo page Friday. In the course of updating the integration to support jqGrid 3.7.2 and simultaneously learning GitHub&#8217;s pages feature, I killed the demo. It&#8217;s fixed now, and I&#8217;ve added the ability to run the unit tests directly from that site, making it easier for me to test [...]]]></description>
      <content:encoded><![CDATA[<p>Apologies to those who tried <a href="http://blogs.teamb.com/craigstuntz/2010/07/16/38612/">my grid.history demo page</a> Friday. In the course of updating the integration to support jqGrid 3.7.2 and simultaneously learning GitHub&#8217;s pages feature, I killed the demo. It&#8217;s fixed now, and I&#8217;ve added the ability to run the unit tests directly from that site, making it easier for me to test multiple browsers on the demo site, instead of just locally.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38624&amp;akst_action=share-this" onclick="akst_share('38624', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F07%2F19%2F38624%2F', 'grid.history+Demo+Fixed'); return false;" title="Post to del.icio.us, etc." id="akst_link_38624" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=grid.history%20Demo%20Fixed&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F07%2F19%2F38624%2F" id="akst_email_38624" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>grid.history: A New, Free Integration for jqGrid and jQuery BBQ</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/07/16/38612/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/07/16/38612/#comments</comments>
    <pubDate>Fri, 16 Jul 2010 21:25:06 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38612</guid>
    <description><![CDATA[I recently finished an integration between the open source jqGrid and jQuery BBQ libraries. I have released my integration as open source, as well. As with both projects, it is dual-licensed under the MIT and GPL licenses.
jqGrid is a JavaScript grid component with many useful features. I have previously explained how to use it with [...]]]></description>
      <content:encoded><![CDATA[<p>I recently finished an integration between the open source jqGrid and jQuery BBQ libraries. I have released my integration as open source, as well. As with both projects, it is dual-licensed under the MIT and GPL licenses.</p>
<p><a href="http://www.trirand.com/blog/">jqGrid</a> is a JavaScript grid component with many useful features. I have previously explained <a href="http://blogs.teamb.com/craigstuntz/2009/04/14/38200/">how to use it with ASP.NET MVC</a>.</p>
<p><a href="http://benalman.com/projects/jquery-bbq-plugin/">jQuery BBQ</a> is a library which helps you manage proper functionality of the web browser&#8217;s back and forward buttons by changing the fragment (hash) of the URI. Using my integration means that you can have a jqGrid on a web page and the back and forward buttons will work as expected.</p>
<p>To be specific, when you first load a certain page, the grid will probably be on page 1. You could click the next page button on the grid to go to page 2. Without my integration, clicking the back button would not take you back to page 1. With my integration, it will. Similarly, I support the sort and records per page combo box. You can of course extend this yourself to track other grid features.</p>
<p><a href="/files/2010/06/grid-history-demo_2701.png"><img src="/files/2010/06/grid-history-demo_2701.png" alt="" width="499" height="298" /></a></p>
<p>The image above shows<a href="http://craigstuntz.github.com/jqGrid/"> a demo page I&#8217;ve prepared, which you try for yourself</a>. The grid on the left does not use the history plug-in. The grid on the right does. Note that when you page, sort, or change the number of rows shown in the grid with the history, the URI fragment also changes.</p>
<p>I have contributed my plug-in back to the jqGrid project. You can get the source from <a href="http://github.com/CraigStuntz/jqGrid">github</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38612&amp;akst_action=share-this" onclick="akst_share('38612', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F07%2F16%2F38612%2F', 'grid.history%3A+A+New%2C+Free+Integration+for+jqGrid+and+jQuery+BBQ'); return false;" title="Post to del.icio.us, etc." id="akst_link_38612" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=grid.history%3A%20A%20New%2C%20Free%20Integration%20for%20jqGrid%20and%20jQuery%20BBQ&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F07%2F16%2F38612%2F" id="akst_email_38612" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Replacing Controller.Session in ASP.NET MVC: Is This Wrong?</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/06/17/38613/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/06/17/38613/#comments</comments>
    <pubDate>Thu, 17 Jun 2010 21:44:36 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38613</guid>
    <description><![CDATA[Here&#8217;s some code I wrote:

public class MyBaseController : Controller
{
    // ...
    public new ISession Session { get; private set; }
    // ....
}

ISession is an interface type I wrote which exposes everything I store in the session at runtime. I use constructor injection to assign this to [...]]]></description>
      <content:encoded><![CDATA[<p>Here&#8217;s some code I wrote:</p>
<blockquote>
<pre><code><strong><span style="color: #0000ff">public class</span></strong> <span style="color: #33cccc">MyBaseController</span> : <span style="color: #33cccc">Controller</span>
{
    // ...
<strong>    <span style="color: #0000ff">public new</span></strong> <span style="color: #33cccc">ISession</span> Session { <strong><span style="color: #0000ff">get</span></strong>; <strong><span style="color: #0000ff">private set</span></strong>; }
    // ....
}</code></pre>
</blockquote>
<p><code>ISession</code> is an interface type I wrote which exposes everything I store in the session at runtime. I use constructor injection to assign this to a simple type which maps to the "real" Session during application runtime, and a "mock" session for unit testing. Session, in ASP.NET, is a user-specific cache.</p>
<p>This hides Controller.Session (of type <code>HttpSessionStateBase</code>) and replaces it with a strongly-typed, mockable replacement. Normally I wouldn&#8217;t use <code><strong>public new</strong></code>, but in this specific case it seems like the best way. It stops developers from using the Web-dependent Session property in derived types and forces them to code to the strong-typed interface. But still, it&#8217;s <code><strong>public new</strong></code>, which seems yucky.</p>
<p>What do you think?</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38613&amp;akst_action=share-this" onclick="akst_share('38613', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F06%2F17%2F38613%2F', 'Replacing+Controller.Session+in+ASP.NET+MVC%3A+Is+This+Wrong%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38613" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Replacing%20Controller.Session%20in%20ASP.NET%20MVC%3A%20Is%20This%20Wrong%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F06%2F17%2F38613%2F" id="akst_email_38613" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Book Review: Rework</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/05/25/38608/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/05/25/38608/#comments</comments>
    <pubDate>Tue, 25 May 2010 14:03:19 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38608</guid>
    <description><![CDATA[Rework, by Jason Fried and David Heinemeier Hansson, cannot accurately be described as the "sequel" to the first book to come out of 37 Signals, Getting Real. As a significant percentage of the book seems to be word for word identical to text in Getting Real, I think it&#8217;s more of a "remix." Getting Real [...]]]></description>
      <content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/0307463745?ie=UTF8&amp;tag=learningtowhi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0307463745">Rework</a><img style="border:none !important;margin:0px !important" src="http://www.assoc-amazon.com/e/ir?t=learningtowhi-20&amp;l=as2&amp;o=1&amp;a=0307463745" border="0" alt="" width="1" height="1" />, by Jason Fried and David Heinemeier Hansson, cannot accurately be described as the "sequel" to the first book to come out of 37 Signals, <a href="http://gettingreal.37signals.com/"><em>Getting Real</em></a>. As a significant percentage of the book seems to be word for word identical to text in <em>Getting Real</em>, I think it&#8217;s more of a "remix." <em>Getting Real</em> focused on creating marketable web software, whereas <em>Rework </em>changes the focus ever so slightly to growing a business around marketable web software.</p>
<p>If you&#8217;ve read <em>Getting Real </em>(you can sample it online for free at the link above, and in my opinion it&#8217;s worth the time to do so), or if you&#8217;ve seen one of DHH&#8217;s presentations, then you probably have a good idea of what to expect in <em>Rework</em>. It&#8217;s short, to the point, quotable, and uses 37 Signals as the model for everything that is good about how to run a business. I don&#8217;t fault the authors for being proud of their company, but if you are looking for a dispassionate examination of when it makes sense to run a business in the way that they do versus other ways, you won&#8217;t find it here. You quickly get the idea that the authors look at other methods of running a business <a href="http://www.infoq.com/interviews/David-Hansson">about as fondly as DHH looks at WS-*</a>. Again, this isn&#8217;t necessarily a bad thing. It&#8217;s clearly worked out pretty well for 37 Signals. One can&#8217;t fail to notice, however, that 37 Signals&#8217;s products fit within a pretty narrow spectrum. Will their techniques translate to other markets and other industries? Perhaps; perhaps not. <em>Rework </em>doesn&#8217;t really answer that question.</p>
<p>Did I say quotable? It&#8217;s full of snappy, almost pithy zingers which are so obviously right that they would seem like tautologies if they were not so commonly ignored:</p>
<blockquote>
<ul>
<li>Workaholics aren’t heroes. They don’t save the day, they just use it up. The real hero is already home because she figured out a faster way to get things done.</li>
<li>You’re better off with a kick-ass half than a half-assed whole.</li>
<li>It’s also unfortunate that meetings are typically scheduled like TV shows. You set aside thirty minutes or an hour because that’s how scheduling software works (you’ll never see anyone schedule a seven-minute meeting with Outlook).</li>
</ul>
</blockquote>
<p>I don&#8217;t think these are empty words. I&#8217;m convinced the authors run their company this way. I&#8217;m also convinced it works for them. They took their own advice writing the book, as well:</p>
<blockquote><p>We cut this book in half between the next-to-last and final drafts. From 57,000 words to about 27,000 words. Trust us, it’s better for it. So start chopping. Getting to great starts by cutting out stuff that’s merely good.</p></blockquote>
<p>But I don&#8217;t agree with everything in the book. Sometimes the cuteness of the writing overtakes the point. It&#8217;s generally true that you should focus on the essentials. But they illustrate this with:</p>
<blockquote><p>For example, if you’re opening a hot dog stand, you could worry about the condiments, the cart, the name, the decoration. But the first thing you should worry about is the hot dog. The hot dogs are the epicenter. Everything else is secondary.</p></blockquote>
<p>Guys, next time you&#8217;re in Columbus, look me up, and I&#8217;ll buy you lunch at <a href="http://dirtyfrankscolumbus.com/">Dirty Franks</a>. I respect what you have to say about business, but we have a thing or two to settle about hot dogs.</p>
<p>Indeed, later in the book the authors make this very point quite elegantly, with a more apropos example:</p>
<blockquote><p>When we start designing something, we sketch out ideas with a big, thick Sharpie marker, instead of a ballpoint pen. Why? Pen points are too fine. They’re too high-resolution. They encourage you to worry about things that you shouldn’t worry about yet, like perfecting the shading or whether to use a dotted or dashed line. You end up focusing on things that should still be out of focus.</p></blockquote>
<p>Avoid <a href="http://paul.kedrosky.com/archives/2008/04/fun_with_false.html">false precision</a>.</p>
<p>The point here, after all, is not how to run a hot dog business in particular; it&#8217;s how to run your business. The best way to fail if that is to let details and directions steer you away from the ideas that only you can bring to the table. This is why "look inside yourself" can be a better approach to planning and business strategy than following an off-the-shelf formula. For most people, creating a new, free, application framework is the worst possible way to start a business selling web applications. I&#8217;ve seen many, many people fail at this. Except that for 37 Signals, it worked really well, perhaps because of the specific people who ran the company.</p>
<p>I strongly agree with the authors when they say:</p>
<blockquote><p>Pour yourself into your product and everything around your product too: how you sell it, how you support it, how you explain it, and how you deliver it. Competitors can never copy the you in your product.</p></blockquote>
<p>This is why it&#8217;s OK that <em>Rework </em>can be self-contradictory at times. In one chapter, the authors suggest that you "pick a fight." A good example of this is how <a href="http://www.codinghorror.com/blog/2009/03/whos-your-arch-enemy.html">Stack Overflow was to some degree a response to "hyphen-site."</a> Only a few chapters later, however, the authors say:</p>
<blockquote><p>Focus on competitors too much and you wind up diluting your own vision. Your chances of coming up with something fresh go way down when you keep feeding your brain other people’s ideas. You become reactionary instead of visionary. You wind up offering your competitor’s products with a different coat of paint. If you’re planning to build “the iPod killer” or “the next Pokemon,” you’re already dead. You’re allowing the competition to set the parameters.</p></blockquote>
<p>Self-contradictory? Absolutely. Again, <em>Rework </em>is not a formula for how people with no interest in widgets can start a widget business. It&#8217;s written to provoke the reader, hopefully provoking them into keeping their business focused on what they can uniquely bring to the table.</p>
<p>Naturally, this presumes that the reader is, to some degree, interesting, and has ideas for things which could benefit other people. It&#8217;s not clear to me if everyone has good ideas, but many people don&#8217;t execute them, or if some people don&#8217;t execute good ideas because they don&#8217;t have them. What is clear is that having good ideas and not executing them is little better than not having them.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38608&amp;akst_action=share-this" onclick="akst_share('38608', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F05%2F25%2F38608%2F', 'Book+Review%3A+Rework'); return false;" title="Post to del.icio.us, etc." id="akst_link_38608" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Book%20Review%3A%20Rework&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F05%2F25%2F38608%2F" id="akst_email_38608" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Stir Trek 2: Iron Man Edition Wrap Up</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/05/10/38602/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/05/10/38602/#comments</comments>
    <pubDate>Mon, 10 May 2010 21:46:18 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38602</guid>
    <description><![CDATA[Last Friday, I attended the Stir Trek conference here in Columbus. The day got off to an inauspicious start when I turned on my car. There was a high screaming noise, and acrid black smoke poured out from the engine. I opened the hood, pulled out a burning air-conditioner drive belt, and threw it into [...]]]></description>
      <content:encoded><![CDATA[<p>Last Friday, I attended the <a href="http://www.stirtrek.com/">Stir Trek conference</a> here in Columbus. The day got off to an inauspicious start when I turned on my car. There was a high screaming noise, and acrid black smoke poured out from the engine. I opened the hood, pulled out a burning air-conditioner drive belt, and threw it into the bushes beside me. Now the engine ran fine! (Although, for some reason, this did not reassure my wife.)</p>
<p>The conference is held in a local movie theater. After a day of technical sessions, the attendees would be treated to a screening of Iron Man 2. I wasn&#8217;t able to stay long enough for that, but the technical content was more than worth the time and the measly $25 cost of the conference. The theater was still a great place to have a technical conference. The screens were huge and the seats were comfortable.</p>
<h4>Keynote</h4>
<p><a href="http://molly.com/about.php">Molly Holzschlag</a> was scheduled to be the keynote speaker, but could not fly due to an ear infection and doctors orders. So she gave her keynote address, and a presentation on HTML 5 later on, via Skype, which was probably better than nothing, but only marginally so, given Internet bandwidth not really sufficient for real-time video. It at least provided some amusement when poorly-timed drop outs turned innocuous technical material into profanities. The HTML 5 presentation suffered from a lack of slides, which Molly made up for by asking us to imagine HTML DOCTYPEs and the like. I appreciate Molly going the extra mile to not leave the conference in the cold, but I didn&#8217;t get a lot out of these sessions, which is too bad, because HTML 5 is an ongoing concern for me right now.</p>
<h4><span>Seeing  Constraints, Kanban Explained</span></h4>
<p>Generally, I rank conference presentations by whether or not I come out of them with useful information or ideas that I can put into practice back at work. <a href="http://www.stirtrek.com/Session.aspx?id=6">The Kanban session</a> did succeed in that respect. The speaker&#8217;s style was very conversational, almost off-the-cuff. He is a process consultant and related a lot of anecdotes about situations he has worked in.</p>
<p>One thing he emphasized which I do not see in much of the writing about Kanban is to use multiple boards when appropriate. For example, a development team can have "their own" board for non-functional changes, which might not ever appear on a board for company-wide items. You can go crazy with this, however; the speaker described one case where something like 36 boards were in use.</p>
<p>This session, like many presentations on development process, tended to presume that development throughput was a bottleneck in the company. This is often the case, but not always. What to do when development is not the bottleneck is a subject which could use fuller treatment.</p>
<h4>Understanding User Experience Patterns</h4>
<p>Since the original notion of a "design pattern" comes from Christopher Alexander&#8217;s writings on architecture (see Patterns of Software, by <a href="http://www.dreamsongs.com/Books.html">Richard P. Gabriel</a>, for more info on this), it makes sense that software companies would want to apply design patterns to more than just code structure. Although there are a number of online user experience <a href="http://quince.infragistics.com/">pattern</a> <a href="http://developer.yahoo.com/ypatterns/">catalogs</a>, it still strikes me that this is an area where we, as an industry, have a lot to learn.</p>
<p>I very much enjoyed Ambrose Little&#8217;s <a href="http://www.stirtrek.com/Session.aspx?id=9">presentation on UX patterns</a>. He showed examples of good and bad interfaces, and discussed why they succeed or fail. He then tied those reasons into pattern catalogs, and demonstrated several of the online catalogs and discussed their strengths and weaknesses.</p>
<h4>jQuery 1.4: What You Need to Know</h4>
<p>For some reason, the lunchtime sessions were not in the Stir Trek catalog, so I will link <a href="http://github.com/ihumanable/stir-trek-2010-jquery-14">Matt&#8217;s slides</a> instead. Matt used a lightweight framework to display his slides using HTML and JavaScript instead of a tool like PowerPoint. This allowed him to demonstrate jQuery features right in the slides. It&#8217;s a very effective way of presenting his subject matter. There wasn&#8217;t a lot of new material in this presentation, given that jQuery 1.4 has been out for a while. It was a good overview, though.</p>
<h4><span>Is Mobile Development Going to Follow the Book of Jobs (Steve That Is)?</span></h4>
<p><a href="http://www.stirtrek.com/Session.aspx?id=15">This presentation</a> was a lot like its title. Opinionated and verbose, but with an attempt to keep things fun the whole time. The presenter has been working in the mobile space for a long time, and has more than his share of war stories. Like a lot of people in mobile work, though, it seems to me that his opinions were colored by the specific nature of the work his company does. The speaker seemed to treat browser apps and web apps as the same thing. <a href="http://www.tbray.org/ongoing/When/201x/2010/05/05/HTML5-and-the-Web">"Native" apps can be web apps.</a> <a href="http://www.phonegap.com/">Browser apps can be local.</a> Web app doesn&#8217;t necessarily mean "in the browser." HTML/JS isn&#8217;t necessarily a web app, especially in the mobile space. Overall, though, I enjoyed this a lot, though I&#8217;m not sure I&#8217;m going to take practical info home with me.</p>
<h4>JQueryUI – The Magic From Behind The Curtain</h4>
<p>Watching <a href="http://www.stirtrek.com/Session.aspx?id=18">this presentation</a> was a bit like playing with the <a href="http://jqueryui.com/demos/">jQuery UI demo page</a>. Still, it exposed me to some features that I haven&#8217;t seen before. The presenter kept things fun, and I left the session feeling like I&#8217;ve learned something.</p>
<h4>Conclusion</h4>
<p>The Stir Trek organizers, who, as far as I know, are all volunteers, did an amazing job creating an event for 600 people that cost so little and delivered so much value. I haven&#8217;t even discussed the freebies like the O&#8217;Reilly e-book and the discounts on training, etc. Don&#8217;t miss this conference next year!</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38602&amp;akst_action=share-this" onclick="akst_share('38602', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F05%2F10%2F38602%2F', 'Stir+Trek+2%3A+Iron+Man+Edition+Wrap+Up'); return false;" title="Post to del.icio.us, etc." id="akst_link_38602" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Stir%20Trek%202%3A%20Iron%20Man%20Edition%20Wrap%20Up&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F05%2F10%2F38602%2F" id="akst_email_38602" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>In LINQ, Don&#8217;t Use Count() When You Mean Any()</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/04/21/38598/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/04/21/38598/#comments</comments>
    <pubDate>Wed, 21 Apr 2010 21:01:29 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Databases]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38598</guid>
    <description><![CDATA[If you have a list, array, or query in a C#/LINQ application and need to check and see if the list is empty, the correct way to do this is to use the Any() extension method:

if (q.Any())
{

Similarly, you can check to see if any elements in the list meet a certain condition:

if (q.Any(i =&#62; i.IsSpecial))
{

If [...]]]></description>
      <content:encoded><![CDATA[<p>If you have a list, array, or query in a C#/LINQ application and need to check and see if the list is empty, the correct way to do this is to use <a href="http://msdn.microsoft.com/en-us/library/bb534338.aspx">the <code>Any()</code> extension method</a>:</p>
<blockquote>
<pre><code>if (q.Any())
{</code></pre>
</blockquote>
<p>Similarly, you can check to see if any elements in the list meet a certain condition:</p>
<blockquote>
<pre><code>if (q.Any(i =&gt; i.IsSpecial))
{</code></pre>
</blockquote>
<p>If the query provider is something like LINQ to Entities, this will be translated into fairly efficient SQL using <code>EXISTS</code>.</p>
<p>For some reason, I see a lot of people write this code using the <code>Count()</code> extension method instead (maybe they don&#8217;t know about <code>Any()</code>?), like this:</p>
<blockquote>
<pre><code>if (q.Count() &gt; 0)
{</code></pre>
</blockquote>
<p>This is wrong for two reasons:</p>
<ul>
<li>It&#8217;s imperative instead of expressive. Using <code>Any()</code> tells the query provider, "Please determine if the list is non-empty using the most efficient way you can." Using <code>Count() &gt; 0</code> tells the query provider, "Please do exactly what I tell you, regardless of what I really need." Because LINQ is intended to support a variety of query providers, it is important to be expressive instead of imperative, and to let the provider specialize the implementation.</li>
<li>Because we don&#8217;t actually care about the exact count of items in the list, only that it is greater than zero, using the <code>Count()</code> function can cause the provider to do considerably more work than necessary. Consider a linked list, or a SQL-based provider.</li>
</ul>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38598&amp;akst_action=share-this" onclick="akst_share('38598', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F04%2F21%2F38598%2F', 'In+LINQ%2C+Don%26%238217%3Bt+Use+Count%28%29+When+You+Mean+Any%28%29'); return false;" title="Post to del.icio.us, etc." id="akst_link_38598" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=In%20LINQ%2C%20Don%26%238217%3Bt%20Use%20Count%28%29%20When%20You%20Mean%20Any%28%29&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F04%2F21%2F38598%2F" id="akst_email_38598" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>A Math Primer for Gentry&#8217;s Fully Homomorphic Encryption</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/04/08/38577/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/04/08/38577/#comments</comments>
    <pubDate>Thu, 08 Apr 2010 18:07:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38577</guid>
    <description><![CDATA[A couple of weeks ago, I wrote What Is Homomorphic Encryption, and Why Should I Care? In that post, I promised to share my C# implementation of the algorithm from Craig Gentry&#8217;s CACM article. Before I can do that, though, I need to explain some of the math involved.
Perhaps surprisingly, it&#8217;s actually very simple. (I [...]]]></description>
      <content:encoded><![CDATA[<p>A couple of weeks ago, I wrote <a href="http://blogs.teamb.com/craigstuntz/2010/03/18/38566/">What Is Homomorphic Encryption, and Why Should I Care?</a> In that post, I promised to share my C# implementation of the algorithm from Craig Gentry&#8217;s CACM article. Before I can do that, though, I need to explain some of the math involved.</p>
<p>Perhaps surprisingly, it&#8217;s actually very simple. (I say "surprisingly" because much of the math and technical papers on encryption is decidedly not simple, including that of <a href="http://crypto.stanford.edu/craig/">Gentry&#8217;s first fully homomorphic scheme</a>, which was based on <a href="http://planetmath.org/encyclopedia/MaximalIdeal2.html">ideal lattices</a>.)</p>
<p>This scheme created by Marten van Dijk, Craig Gentry, Shai Halevi and Vinod Vaikuntanathan, however, uses basic arithmetic operations like division, with a few uncommon, but easy to understand, variations.</p>
<p>The nature of homomorphic encryption also dictates a programming style which will seem unfamiliar to users of most high-level languages, but very familiar to anyone who has ever taken a digital circuits class.</p>
<h2>Integer Division</h2>
<p>What is the integer quotient of 10 / 6? Most people would probably  say "1, remainder 4." But the exact answer, in the domain of real  numbers, is 1.666666 (repeating), which is closer to 2 than the previous  answer of 1. So another way we could answer this question is "2,  remainder -2." This quotient is closer to the exact answer, and,  correspondingly, has a smaller remainder.</p>
<p>So which answer is correct? Arguably, both of them. As long as the following rule holds:</p>
<blockquote><p><code>dividend = divisor * quotient + remainder </code> (the division rule)</p></blockquote>
<p>&#8230;then we have a valid answer.</p>
<p>Which method should you use? <em>It depends on why you&#8217;re doing the division.</em> If you&#8217;re computing how many cupcakes each child can have at a birthday party, then you&#8217;d better use the answer with the positive remainder. If you&#8217;re computing how many panels of fencing you need to surround your yard, then you&#8217;d better use the answer with the negative remainder.</p>
<p>In fact, there are at least <a title="Division and Modulus for Computer Scientists [PDF]" href="http://legacy.cs.uu.nl/daan/download/papers/divmodnote.pdf">five different, valid algorithms</a> for selecting a quotient and remainder for a given integer division problem.</p>
<p>The homomorphic encryption scheme used in the van Dijk, et. al. paper and in Gentry&#8217;s CACM article uses "R-division":</p>
<ol>
<li>Compute the real quotient <code>Q<sub>R</sub></code>.</li>
<li>Compute the integer quotient <code>Q<sub>Z</sub></code> by rounding <code>Q<sub>R</sub></code> to the closest integer.</li>
<li>Compute the remainder <code>R = Dividend - Divisor * Q<sub>Z</sub></code></li>
</ol>
<p>This is probably different than the method you learned in elementary  school, but both are valid. Importantly, it&#8217;s probably different than what the integer division and remainder operators in your favorite programming language do.</p>
<h2>Modular Arithmetic</h2>
<p><a href="http://etc.usf.edu/clipart/33400/33474/clock-10-00_33474.htm"><img style="float: right" src="/files/2010/03/clock-10-0033474sm_2452.gif" alt="" width="200" height="200" /></a>If you&#8217;ve ever seen a 12 hour, analog clock, then you&#8217;ve worked with modular arithmetic. The time of 10:00 today is the same position on the clock as 10:00 p.m/22:00. Another way to say this is:</p>
<blockquote><p><code>10 ≡ 22 mod 12</code></p></blockquote>
<p>This reads: "10 is congruent to 22 modulo 12." In other words, we just ignore the "extra" 12 hours in the measurement of 22:00, because it&#8217;s the same clock dial position as 22:00, only with a circle around the dial.</p>
<p>Naturally, we can perform arithmetic operations like addition and subtraction and compare the congruence of the result. I can say "10:00 + 5 hours means that the hour hand will point to 3 on the clock," or:</p>
<blockquote><p><code>10 + 5 ≡ 3 mod 12</code></p></blockquote>
<h2>Modulo 2 Arithmetic and Binary Operations</h2>
<p>You can use any number as the modulus. When we make analog clocks, we use 12. A modulus which is particularly interesting in computer programming is 2. Arithmetic operations mod 2 correspond to binary operations, e.g.:</p>
<blockquote><p><code>0 + 0 ≡ 0 mod 2<br />
0 + 1 ≡ 1 mod 2<br />
1 + 0 ≡ 1 mod 2<br />
1 + 1 ≡ 0 mod 2</code></p></blockquote>
<p>From this example, you can see that addition modulo 2 is the same as the binary operation <code>XOR</code>. It turns out that subtraction is exactly the same thing (for mod 2 only!):</p>
<blockquote><p><code>0 - 0 ≡ 0 mod 2<br />
0 - 1 ≡ 1 mod 2<br />
1 - 0 ≡ 1 mod 2<br />
1 - 1 ≡ 0 mod 2</code></p></blockquote>
<p>Multiplication modulo 2, on the other hand, corresponds to the binary operation <code>AND</code>:</p>
<blockquote><p><code>0 * 0 ≡ 0 mod 2<br />
0 * 1 ≡ 0 mod 2<br />
1 * 0 ≡ 0 mod 2<br />
1 * 1 ≡ 1 mod 2</code></p></blockquote>
<h2>Mod in Programming</h2>
<p>This is all very simple. However, a word of caution is in order here for anyone who has used a high-level programming language. Most languages have an operator like <code>mod</code> (in Delphi) or <code>%</code> (in C#, which is commonly pronounced "mod"). However, this operator is not strictly modular congruence. It is more like a remainder, although, as we&#8217;ve seen, different people and different programming languages might choose to compute a remainder in different (but hopefully valid) ways.</p>
<p>Remainders and congruence are often the same. In fact, the congruence relationship and the integer division remainder for the examples above are <em>all </em>the same. For example:</p>
<blockquote><p><code>10 ≡ 22            mod 12<br />
22 / 12 = 1 R 10</code></p></blockquote>
<p>However, it&#8217;s easy to show examples where this is not true:</p>
<blockquote>
<pre><code>22 ≡ 34              mod 12       (1)
34 / 12 = 2 R 10                  (2)
-22 ≡ 2              mod 12       (3)
-22 / 12 = -1 R -10               (4)
</code></pre>
</blockquote>
<p>(1) is probably not the most common choice; 10 would be a more common answer, as with (2). (1) is nevertheless correct as a statement of congruence. Now compare (3) with (4). The most common way to compute a modulus is to pick the smallest positive number. But the most common way to perform integer division is so-called "T-division", where you select the quotient closest to zero and then calculate the remainder, resulting in a negative remainder when either the dividend or the divisor is negative.</p>
<h2>Programs as Digital Circuits</h2>
<p>A homomorphic encryption scheme, in addition to the usual <code>Encrypt</code> and <code>Decrypt</code> and <code>KeyGen</code> functions, has an <code>Evaluate</code> function which performs operations on the ciphertext, resulting in the ciphertext of the result of the function.</p>
<p>Obviously, this necessitates a different style of programming than that afforded by the typical programming language. In particular, code like this:</p>
<blockquote>
<pre><code><strong>bool</strong> a = b ? c : d</code></pre>
</blockquote>
<p>&#8230;(where <code>a</code>, <code>b</code>, <code>c</code>, and <code>d</code> are all <code>bool</code>s) is impossible, because the value of <code>b</code> is encrypted, so the program cannot know what to assign to <code>a</code>. If, however, we can perform binary operations on the ciphertext of <code>b</code>, then we can rewrite the statement above as:</p>
<blockquote>
<pre><code><strong>bool</strong> a = (b &amp; c) | ((!b) &amp; d)</code></pre>
</blockquote>
<p>&#8230;or its homomorphic encryption equivalent:</p>
<blockquote>
<pre><code><strong>CypherText</strong> a = (b h_and c) h_or (h_not(b) h_and d)</code></pre>
</blockquote>
<p>&#8230;where the <code>h_*</code> operators are the homomorphic equivalents of the usual Boolean operations and <code>a</code>, <code>b</code>, <code>c</code>, and <code>d</code> are now of type <code>CypherText</code>.</p>
<p>Note that the version with the ternary operator and the version with the <code>AND</code> and <code>OR</code> operators are not strictly the same, although their results are; the ternary operator is lazy, whereas the <code>AND</code> and <code>OR</code> version uses complete evaluation. This is necessary when the values are encrypted. It also means that the function may be inefficient.</p>
<p>Intuitively, it&#8217;s easy to see that any <a href="http://en.wikipedia.org/wiki/Referential_transparency_%28computer_science%29">referentially transparent</a> function can be reduced to such operations; this is what compilers and operating systems do under the hood anyway. I&#8217;m not going to go into any detail on how this is done; <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2Fs%3Fie%3DUTF8%26x%3D0%26ref_%3Dnb%5Fsb%5Fss%5Fc%5F1%5F11%26y%3D0%26field-keywords%3Ddigital%2520circuits%26url%3Dsearch-alias%253Dstripbooks%26sprefix%3Ddigital%2520cir&amp;tag=learningtowhi-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=390957">get an introduction to digital circuits book</a><img style="border:none !important;margin:0px !important" src="https://www.assoc-amazon.com/e/ir?t=learningtowhi-20&amp;l=ur2&amp;o=1" border="0" alt="" width="1" height="1" /> if you are interested in the particulars.</p>
<p>Gentry&#8217;s article notes that other changes in programming style are necessary when performing operations within a homomorphic encryption scheme. For example, the size of the output of a function must be set in advance. Even if the plaintext is variable-length, the ciphertext must be of a known length, which corresponds to the number of "wires" in the circuit. The plaintext, therefore, would have "whitespace" at the end or be truncated, depending upon its size.</p>
<h2>Minimizing Boolean Functions</h2>
<p>In <a href="http://blogs.teamb.com/craigstuntz/2010/03/18/38566/">my first post on homomorphic encryption</a>, I mentioned that Gentry&#8217;s encryption schemes can be considered fully homomorphic because they support two homomorphic operations, corresponding to Boolean <code>AND</code> and <code>XOR</code>. I&#8217;d like to go into a little bit more detail as to why that is true.</p>
<p>Many combinations of Boolean operations are equivalent. Perhaps the most famous are <a href="http://en.wikipedia.org/wiki/De_Morgan%27s_laws">De Morgan&#8217;s laws</a>. There are <a title="Minimizing Boolean Functions" href="http://babbage.cs.qc.edu/courses/Minimize/">a variety of techniques for converting one function using Boolean operations into an equivalent function with different operations</a>. This is often done in order to produce a <a title="Boolean rules for simplification" href="http://www.allaboutcircuits.com/vol_4/chpt_7/5.html">simpler</a> or more efficient function, but can also be done in order to use a specific type of Boolean gate.</p>
<p>It is possible to use <a href="http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/nand.html#c4">combinations of <code>NAND</code> or <code>NOR</code> gates, for example, to produce circuits which perform a Boolean AND, OR, NOT, etc.</a> Hence, a cryptosystem which supported a homomorphic <code>NAND</code> operation could be considered "fully homomorphic."</p>
<p>Similarly, having both <code>AND</code> and <code>XOR</code> gates available allows you to produce the same outputs as all other Boolean gates, as, for example, <code>NOT p</code> is the same as <code>p XOR 1</code> and we can see by De Morgan&#8217;s laws that with <code>NOT</code> and <code>AND</code> we can implement <code>OR</code>.</p>
<p>Therefore, we can see that a cryptosystem can be considered fully homomorphic if it supports enough homomorphic operations to perform any logical Boolean operation. In particular, a cryptosystem which supports any of the following homomorphic operations would qualify:</p>
<ul>
<li>Just <code>NAND</code></li>
<li>Just <code>NOR</code></li>
<li>Both <code>XOR</code> and <code>AND</code></li>
</ul>
<h2>What&#8217;s Next</h2>
<p>If you understand the math above, you should now be able to follow along as I implement Gentry&#8217;s algorithm for "somewhat homomorphic" encryption. As you&#8217;ll see, the "somewhat homomorphic" encryption will be the first step towards a fully homomorphic cryptosystem.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38577&amp;akst_action=share-this" onclick="akst_share('38577', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F04%2F08%2F38577%2F', 'A+Math+Primer+for+Gentry%26%238217%3Bs+Fully+Homomorphic+Encryption'); return false;" title="Post to del.icio.us, etc." id="akst_link_38577" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=A%20Math%20Primer%20for%20Gentry%26%238217%3Bs%20Fully%20Homomorphic%20Encryption&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F04%2F08%2F38577%2F" id="akst_email_38577" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Want to Beta Test the Next Version of InterBase?</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/03/18/38574/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/03/18/38574/#comments</comments>
    <pubDate>Thu, 18 Mar 2010 20:08:14 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38574</guid>
    <description><![CDATA[The InterBase roadmap says that the next version will probably include native 64 bit and Windows 7 support, cloud deployment, and enhance password security. Want to help beta test it? You can sign up now.
]]></description>
      <content:encoded><![CDATA[<p>The <a href="http://edn.embarcadero.com/article/40179">InterBase roadmap</a> says that the next version will probably include native 64 bit and Windows 7 support, cloud deployment, and enhance password security. Want to help beta test it? <a href="http://www.embarcadero.com/products/beta-programs">You can sign up now</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38574&amp;akst_action=share-this" onclick="akst_share('38574', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F18%2F38574%2F', 'Want+to+Beta+Test+the+Next+Version+of+InterBase%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38574" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Want%20to%20Beta%20Test%20the%20Next%20Version%20of%20InterBase%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F18%2F38574%2F" id="akst_email_38574" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>What is Homomorphic Encryption, and Why Should I Care?</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/03/18/38566/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/03/18/38566/#comments</comments>
    <pubDate>Thu, 18 Mar 2010 17:08:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38566</guid>
    <description><![CDATA[The March 2010 issue of the Communications of the ACM includes a technical paper with an introduction entitled "A First Glance of Cryptography&#8217;s Holy Grail" (ACM subscription required). That&#8217;s enough to catch my attention. The paper itself, Computing Arbitrary Functions of Encrypted Data, describes a relatively new algorithm for homomorphic encryption.
Although these words may be [...]]]></description>
      <content:encoded><![CDATA[<p>The <a href="http://cacm.acm.org/magazines/2010/3">March 2010 issue of the Communications of the ACM</a> includes a technical paper with an introduction entitled "<a href="http://cacm.acm.org/magazines/2010/3/76275-a-first-glimpse-of-cryptographys-holy-grail">A First Glance of Cryptography&#8217;s Holy Grail</a>" (<a href="http://campus.acm.org/public/qj/QuickJoin/interim.cfm">ACM subscription</a> required). That&#8217;s enough to catch my attention. The paper itself, <a href="http://cacm.acm.org/magazines/2010/3/76272-computing-arbitrary-functions-of-encrypted-data">Computing Arbitrary Functions of Encrypted Data</a>, describes a relatively new algorithm for homomorphic encryption.</p>
<p>Although these words may be unfamiliar to many, the subject matter is terribly important, because, like public-key encryption, which paved the way for secure transactions over the web, an efficient and fully homomorphic encryption scheme would enable new kinds of distributed computing. I&#8217;ll explain more about this in a little bit.</p>
<p>If you have an ACM membership, or can find the magazine in a library, I recommend the article. It is far and away more readable than the technical papers on the same subject which are available on the web. The article uses a running analogy of a jeweler who doesn&#8217;t quite trust her employees in order to help the reader understand the design of the system.</p>
<h2>What Is Homomorphic Encryption?</h2>
<p>"Homomorphic" is an adjective which describes a property of an encryption scheme. That property, in simple terms, is the ability to perform computations on the ciphertext without decrypting it first. Because this tends to sound either baffling or miraculous the first time you hear it, let&#8217;s begin with a very simple example.</p>
<p>The popular but wildly insecure cipher scheme <a href="http://www.rot13.com/info.php">rot-13</a> (a.k.a. "<a href="http://en.wikipedia.org/wiki/Caesar_cipher">Caesar cipher</a>") is partially homomorphic, specifically with respect to the concatenation operation. Imagine we write an <code>Encrypt</code> and <code>Decrypt</code> function using the rot-13 algorithm. The "secret key" will be 13, the number of characters each letter is shifted. Let&#8217;s encrypt two words and then concatenate the ciphertext, and finally decrypt the result. In psuedocode, this is:</p>
<blockquote>
<pre><code>var c1 = Encrypt(13, "HELLO");      // c1 = URYYB
var c2 = Encrypt(13, "WORLD");      // c2 = JBEYQ
var c3 = Concat (c1, c2);           // c3 = URYYBJBEYQ
var p  = Decrypt(13, c3);           // p  = HELLOWORLD</code></pre>
</blockquote>
<p>Because it was not necessary to first decrypt the two fragments of ciphertext before performing the concatenation operation, we can say that rot-13 is homomorphic with respect to concatenation.  In other words, it is possible to take two pieces of ciphertext and perform an operation on them which results in the ciphertext of the concatenation of the two respective pieces of plaintext.</p>
<p>Visually, it looks like this:</p>
<p><img src="http://i43.tinypic.com/akjwaw.png" border="0" alt="Homomorphic concat with Rot-13" /></p>
<p>It just so happens that in this case the homomorphic concatenation (concatenating the two fragments of ciphertext) is the same operation as the non-homomorphic concatenation (concatenating two fragments of plaintext). This is not always the case. What is important is that we can perform some operation on the input ciphertext which will produce new ciphertext that, when decrypted, will produce output plaintext corresponding to a desired operation on the input plaintext.</p>
<p>Although rot-13 is not at all secure, it turns out that some cryptosystems widely believed to be secure have homomorphic properties. For example, "pure" and un-padded RSA is homomorphic with respect to multiplication.</p>
<h2>Why Should I Care?</h2>
<p>All of this may seem academically interesting, but one might wonder why I started this post claiming that "an efficient and fully homomorphic encryption scheme would enable new kinds of distributed computing."</p>
<p>I think that the scenario which best makes the benefits of homomorphic encryption clear is cloud computing. <a title="Experience Curves for Data Center Hosting" href="http://www.cloudcomputingeconomics.com/2009/01/experience-curves-for-data-center.html">It is often much more economical to buy computing resources from a cloud provider then to build a data center yourself</a>. This is especially true if your need for computing horsepower fluctuates. But what if you want to do this computing on private data? Maybe you trust your cloud provider, but what if trust is not enough? Is there a way to get the compelling economic benefits of cloud computing while keeping your data secure?</p>
<p>Imagine that you have developed a web application for income tax preparation. Your application collects personal and financial information from the user, creates a tax strategy resulting in the lowest possible (legal!) income tax payment, and submits the prepared return to the <a href="http://www.irs.gov/">IRS</a>. From a business point of view, this application might be compelling, but it&#8217;s a daunting task operationally. In the United States, most people file their taxes once a year, before April 15th. This means that your servers will see a huge spike in demand in the first quarter of the year, with relatively little demand other times. Also, potential customers might be understandably wary about uploading their personal information and financial data to the website of a new business.</p>
<p>Cloud computing offers an excellent answer to the first problem. Because you buy computing resources on as-needed basis, it is very easy to increase the number of available servers when tax season arrives, and reduce the number at other times. Unfortunately, it doesn&#8217;t do anything for the second problem.</p>
<p>Hard security in the cloud is not really possible today. It&#8217;s very easy to have secure transmission from a local machine to a cloud data store, and of course the stored data can be encrypted. But actually performing computations on that data in the cloud requires decrypting it first. Anyone with physical access to the machine, therefore, has access to your data.</p>
<p>What if it were possible for a user of your tax preparation software to upload their financial information encrypted under the IRS&#8217;s public key? Then their data would be secure. You can do this today, of course, but your software would be unable to select a tax strategy for the user or prepare forms. If, however, the encryption method used was also fully homomorphic, then your software could do all of this work without first decrypting the user&#8217;s information. The output of your software would be a tax return encrypted under the IRS&#8217;s public key. Only the IRS could decrypt it.</p>
<h2>Fully Homomorphic Encryption</h2>
<p>So a fully homomorphic encryption scheme would seem to solve the security problem while still being compatible with a cloud deployment scenario. Unfortunately, preparing a tax return requires more than just a Concat operation. We can say that an encryption scheme is "fully homomorphic" if it supports enough homomorphic operations to implement any function we need. I&#8217;m being purposely imprecise here, because the details are a bit of a digression at this point.</p>
<p>Although there are <a href="http://en.wikipedia.org/wiki/Homomorphic_encryption">a number of encryption schemes with one homomorphic operation</a>, until recently no one was really sure if fully homomorphic encryption was even possible. Rivest, Adleman, and Dertouzos               suggested that fully homomorphic encryption may be  possible in               1978, but were unable to find               a secure scheme. <a href="http://crypto.stanford.edu/~dabo/abstracts/2dnf.html">Another scheme, from Boneh, et. al.</a>, supports two operations, but you can only perform one of them once.</p>
<p>When you consider the complexity of a typical programming language, two operations doesn&#8217;t sound like very many, but since we are only looking at operations which mutate data (as opposed to keeping track of the current instruction pointer, etc.) it turns out that supporting the <code>and</code> and <code>xor</code> operations is enough to consider a scheme fully homomorphic, <em>if </em>you can perform those operations an unlimited number of times.</p>
<p>So it was <a title="IBM press release" href="http://www-03.ibm.com/press/us/en/pressrelease/27840.wss">big news</a> when Craig Gentry managed to create such a scheme as part of <a href="http://crypto.stanford.edu/craig/">his Stanford doctoral thesis</a>. Gentry, along with several other researchers from IBM and MIT later created <a title="Fully Homomorphic Encryption over the Integers" href="http://eprint.iacr.org/2009/616">yet another scheme</a> using a different encryption technique, but a similar general approach, with similar homomorphic properties.</p>
<p>Some would say "too big." <a title="Homomorphic Encryption Breakthrough" href="http://www.schneier.com/blog/archives/2009/07/homomorphic_enc.html">Bruce Schneier criticized the IBM press release</a> for implying, in his reading, that Gentry&#8217;s scheme was practical for real applications, today. It isn&#8217;t; the computational and data storage overheads are far too high. However, this takes nothing away from Gentry&#8217;s achievement; he has shown that fully homomorphic encryption is actually possible. Indeed, Schneier concludes:</p>
<blockquote><p>Visions of a fully homomorphic cryptosystem have been dancing in  cryptographers&#8217; heads for thirty years.  I never expected to see one.   It will be years before a sufficient number of cryptographers examine  the algorithm that we can have any confidence that the scheme is secure,  but &#8212; practicality be damned &#8212; this is an amazing piece of work.</p></blockquote>
<h2>Let&#8217;s Code It!</h2>
<p>The second, fully homomorphic scheme proposed by Gentry, et al., and described in the CACM article is simple enough that I decided to implement it myself. I&#8217;ve learned quite a lot in the process of doing this. So in the near future I&#8217;ll be sharing my code and some of the insights I&#8217;ve made in this process.</p>
<p>Before I can do that, however, <a title="A Math Primer for Gentry’s Fully Homomorphic Encryption" href="http://blogs.teamb.com/craigstuntz/2010/04/08/38577/">I need to describe some of the math involved</a>. And I&#8217;d like to elaborate on why two operations is enough to consider a scheme "fully homomorphic."</p>
<p>(<a href="http://blogs.teamb.com/craigstuntz/2010/04/08/38577/">Continue reading&#8230;</a>)</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38566&amp;akst_action=share-this" onclick="akst_share('38566', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F18%2F38566%2F', 'What+is+Homomorphic+Encryption%2C+and+Why+Should+I+Care%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38566" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=What%20is%20Homomorphic%20Encryption%2C%20and%20Why%20Should%20I%20Care%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F18%2F38566%2F" id="akst_email_38566" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Don&#8217;t Depend Upon the ASP.NET Membership Tables</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/03/05/38558/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/03/05/38558/#comments</comments>
    <pubDate>Fri, 05 Mar 2010 20:48:27 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38558</guid>
    <description><![CDATA[One very popular option for implementing user security in ASP.NET is to use Forms Authentication with the SQL Server membership provider. This provider creates several database tables to store user-related information, as well as a number stored procedures.
From time to time, a developer will attempt to add the ASP.NET Membership/Forms Authentication tables to their Entity [...]]]></description>
      <content:encoded><![CDATA[<p>One very popular option for implementing user security in ASP.NET is to <a href="http://msdn.microsoft.com/en-us/library/ms998317.aspx">use Forms Authentication with the SQL Server membership provider</a>. This provider creates several database tables to store user-related information, as well as a number stored procedures.</p>
<p>From time to time, a developer will attempt to add the ASP.NET Membership/Forms Authentication tables to their Entity Framework model (or LINQ to SQL, NHibernate, etc.) model. Before doing this, they will often have created referential constraints against these tables. When the mapping doesn&#8217;t work out quite the way they planned, <a href="http://stackoverflow.com/search?q=[entity-framework]+aspnet_users">they will ask how to make the mapping work</a>.</p>
<p><strong>There&#8217;s only one correct answer to this question: Don&#8217;t do it at all!</strong></p>
<p>There are a number of good reasons why you should not make your database and code depend upon the SQL Membership Provider database schema. In this post, I will focus on a few of the most important:</p>
<ul>
<li>Separation of concerns</li>
<li>Membership and authentication providers are supposed to be interchangeable</li>
<li>The SQL Membership Provider database schema is an implementation detail</li>
</ul>
<h3>Separation of Concerns</h3>
<p>Your application&#8217;s data model is designed to fit your application domain. It will change based upon the needs of the end users. It should not have to change because Microsoft decides to update the SQL membership provider, as well. That would violate the <a href="http://www.oodesign.com/single-responsibility-principle.html">single responsibility principle</a>. It is often <a title="Commercial Suicide Integration at the Database Level" href="http://devlicio.us/blogs/casey/archive/2009/05/14/commercial-suicide-integration-at-the-database-level.aspx">dangerous to combine data which is not closely related into a single data model</a>. This danger is compounded when data from two separate domains, written by entirely different companies, and designed for orthogonal purposes is shoehorned into a single entity model.</p>
<h3>Membership providers are supposed to be interchangeable</h3>
<p>One of the most important design intentions of the ASP.NET authentication and membership provider model is to make it easy to interchange providers. If you decide to stop using the SQL membership provider in transition to Open ID, domain authentication, Facebook authentication, etc., this should be a matter of, at most, a couple of days work to migrate data from one provider to the other, rather than a complete rewrite of your application, starting with the database and moving out from there.</p>
<h3>The SQL Membership Provider database schema is an implementation detail</h3>
<p>The publicly-documented interfaces to membership and forms authentication are the <a href="http://msdn.microsoft.com/en-us/library/system.web.security.membership.aspx">Membership</a> and <a href="http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.aspx">FormsAuthentication</a> types, respectively, as well as the <a title="authentication Element" href="http://msdn.microsoft.com/en-us/library/532aee0e.aspx">relevant</a> <a title="membership Element" href="http://msdn.microsoft.com/en-us/library/1b9hw62f.aspx">sections</a> of the Web.config file. If you write your code around these types, you have a reasonable expectation that your code will continue to work when the .NET framework is next updated. On the other hand, if you query the database directly, there is no guarantee that the schema will not change when the next version of .NET ships. If Microsoft makes a security-related change to the SQL membership provider, then it is conceivable that the schema could even change with a service pack. The cost of relying on an implementation detail is that you never really know.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38558&amp;akst_action=share-this" onclick="akst_share('38558', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F05%2F38558%2F', 'Don%26%238217%3Bt+Depend+Upon+the+ASP.NET+Membership+Tables'); return false;" title="Post to del.icio.us, etc." id="akst_link_38558" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Don%26%238217%3Bt%20Depend%20Upon%20the%20ASP.NET%20Membership%20Tables&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F03%2F05%2F38558%2F" id="akst_email_38558" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>jqGrid and XSS Security</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/02/08/38548/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/02/08/38548/#comments</comments>
    <pubDate>Mon, 08 Feb 2010 20:50:22 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38548</guid>
    <description><![CDATA[Version 3.5.2 of jqGrid included an important new feature:
Now when autoencode is set to true we encode the data coming from server and not only when we post it (secutity fix)
Prior to this, you were required to encode the data yourself.
Now personally, I think that should be the default. But it would have been a [...]]]></description>
      <content:encoded><![CDATA[<p>Version 3.5.2 of <a href="http://www.trirand.com/blog/">jqGrid</a> included <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:change#jqgrid_3.5.2_changes_and_fixes">an important new feature</a>:</p>
<blockquote><p>Now when <code>autoencode</code> is set to true we encode the data coming from server and not only when we post it (secutity fix)</p></blockquote>
<p>Prior to this, you were required to encode the data yourself.</p>
<p>Now personally, I think that should be the default. But it would have been a breaking change for the grid, since there are a few cases where you want to display unencoded data (I&#8217;ll discuss these exceptional cases in a second).</p>
<p>It&#8217;s really easy to make this the default for your application. Set the grid&#8217;s defaults before you create any grids:</p>
<blockquote>
<pre><code>    $.jgrid.defaults = $.extend($.jgrid.defaults, {
            autoencode: true,
            datatype: 'json',
            // etc....</code></pre>
</blockquote>
<p>You can override this in the rare cases when you don&#8217;t want encoded data by setting <code>autoencode</code> false when setting up your grid:</p>
<blockquote>
<pre><code>    $("#grid").jqGrid({
                    autoencode: false,
                    url: "/Some/Path",
                    // etc....,</code></pre>
</blockquote>
<p>So why wouldn&#8217;t you want to use this setting? I can think of two reasons:</p>
<ol>
<li>The server is returning markup which you don&#8217;t want to encode. If you have a server method which is returning markup (e.g., "<code>&lt;img src=</code>&#8230;"), then you won&#8217;t want the grid to encode it. It then becomes your responsibility to sanitize the rest of the grid data on the server.</li>
<li>There is a performance cost to doing the encoding in JavaScript. If you are <em>absolutely certain</em> that the server method you&#8217;re calling can return only sanitized data, then you can turn off the auto encoding and save this cost. Note that many JSON encoders, such as the "<code>Json()</code>" method in ASP.NET MVC will <em>not</em> encode HTML by default.</li>
</ol>
<p>Note that you can only set <code>autoencode</code> at the grid level, not at the column level.</p>
<p>If you use <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:custom_formatter">custom formatters</a> in your grid, then you should note that the strings they return will not be HTML encoded, even if you set <code>autoencode</code> true. This is probably a good thing, since it is common to use custom formatters to return HTML. However, it means that if you write a custom formatter, then you must ensure that any user data contained in the string and returns is encoded. You can use the grid&#8217;s encoder, which is little more than a string replace on angle brackets, in a custom formatter as follows:</p>
<blockquote>
<pre><code>    myFormatter: <strong>function</strong>(cellval, opts, action) {
        <strong>if </strong>(cellval) {
            return $.jgrid.htmlEncode(cellval.Name + "");
        };
        <strong>return </strong>"";
    }</code></pre>
</blockquote>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38548&amp;akst_action=share-this" onclick="akst_share('38548', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F02%2F08%2F38548%2F', 'jqGrid+and+XSS+Security'); return false;" title="Post to del.icio.us, etc." id="akst_link_38548" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=jqGrid%20and%20XSS%20Security&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F02%2F08%2F38548%2F" id="akst_email_38548" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Entity Framework Models and Source Control</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/02/03/38542/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/02/03/38542/#comments</comments>
    <pubDate>Wed, 03 Feb 2010 19:58:19 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Databases]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38542</guid>
    <description><![CDATA[As you&#8217;re probably aware, an Entity Framework model is stored in a single XML file, with the extension EDMX. Developers occasionally ask if this means that two people cannot work on the entity model concurrently. My answer to this is, "It depends." But I can give you some tips to make it easier.
Obviously, if you [...]]]></description>
      <content:encoded><![CDATA[<p>As you&#8217;re probably aware, an Entity Framework model is stored in a single XML file, with the extension EDMX. Developers occasionally ask if this means that two people cannot work on the entity model concurrently. My answer to this is, "It depends." But I can give you some tips to make it easier.</p>
<p>Obviously, if you use a source control tool which locks files on check out, then working concurrently on just about anything will be impossible. So I&#8217;m going to presume that your source control tool supports working concurrently, without locks, and has a decent merge tool to handle conflicts at check-in.</p>
<p>We tend to think of the EDMX files as having three sections:</p>
<ul>
<li><strong>CSDL</strong>, which describes the client schema. This will be used when generating code for your entity classes.</li>
<li><strong>SSDL</strong>, which describes the storage schema, more commonly known as your database metadata.</li>
<li><strong>MSL</strong>, which describes the relationship between the first two.</li>
</ul>
<p>In reality, however, the EDMX file has two main sections. The first, <code>edmx:Runtime</code>, contains the three <em>sub</em>-sections described above. The second, <code>edmx:Designer</code>, contains a couple of important properties, such as <code>MetadataArtifactProcessing</code>, plus <em>a lot</em> of information about the position of objects on the GUI designer, in a sub-node called <code>edmx:Diagrams</code>. The illustration below should make this clear:</p>
<p><a href="/files/2010/02/edmx_2309.png"><img src="/files/2010/02/edmx_2309.png" alt="" width="677" height="203" /></a></p>
<p>Why is this important? My experience is that any decent merge tool doesn&#8217;t tend to have any problem merging what we typically think of as the "EDMX", namely the CSDL, SSDL, and MSL. It is well-formed XML with descriptive tags; it&#8217;s the sort of thing that text merge tools tend to do very well with. There are a couple of tips worth knowing, but before I describe them, I&#8217;d like to focus on the more common issue with EDMX merges.</p>
<p>In my experience, if two people change the layout of entities in the designer and then attempt to merge, the merge will probably fail. Moreover, you will find it difficult to impossible to fix this up manually, something which is generally fairly easy with merges of source code or other parts of the EDMX. When you look at what is in the <code>edmx:Diagrams</code> node, you will quickly understand why:</p>
<p><a href="/files/2010/02/diagrams_2312.png"><img src="/files/2010/02/diagrams_2312.png" alt="" width="500" height="328" /></a></p>
<p>I strongly suspect that this "feature" is not specific to the Entity Framework designer, but rather is shared amongst all of Visual Studio&#8217;s various diagramming tools. At any rate, I think you will have a difficult time merging XML like this, so I have two recommendations regarding merging and EDMX files:</p>
<ul>
<li>If you are going to have two or more developers work on an EDMX file concurrently, then don&#8217;t change anything in the designer. If two or more people do this, it almost guarantees a conflict on check-in.</li>
<li>The other side of the coin is that if you must change something in the designer, then you should give a heads-up to other developers, and exclusively lock the EDMX file while you work.</li>
</ul>
<p>That said, we don&#8217;t generally use the GUI designer at all. It is too unwieldy to have more than a dozen or so types on a single design surface. On the other hand, the tree-style Model Browser is quite useful. I suggest using the Model Browser instead of the GUI designer to navigate your entity model.</p>
<p>Perhaps a future version of the Entity Framework designer will allow for multiple diagrams within a single entity model, somewhat like SQL Server diagrams. If each diagram had its own node in the XML, you might even be able to merge them.</p>
<p>If you steer clear of issues with the designer, then you will typically find that EDMX changes can be automatically merged by any decent merge tool (unless, of course, they actually conflict). In the unlikely event, however, that your merge tool reports a conflict, and you don&#8217;t think it&#8217;s an actual conflict between your changes and those made by the other developer, it does help to understand how the "Update Model from Database" wizard updates existing EDMX:</p>
<ol>
<li>The wizard will generate new SSDL from scratch. It will then go through the newly generated SSDL, and replace each matching node in the existing SSDL with the newly generated version. There are a few SSDL features which are not supported by the designer/wizard, such as will, and these will be left alone, if they exist in your model.</li>
<li>Any new entities or new properties of existing entities will have corresponding nodes added to the CSDL and MSL. But existing entities and properties will not have their CSDL and MSL updated, because the wizard presumes that you want to keep any changes you may have made to them.</li>
</ol>
<p>Therefore, when multiple developers are updating an EDMX file concurrently, they should use the same database. This will tend to make SSDL changes merge without conflict, and allows you to simply overwrite any false conflicts (merge tool failures) in the SSDL, because you can be confident that it was generated from the same object in the same database. But if you&#8217;ve manually customized your SSDL (i.e., edited the SSDL section of the EDMX as text), then you should keep an eye on your changes, to make sure that the wizard does not overwrite them. Most people never do this, though.</p>
<p>On the other hand, changes to the CSDL and MSL must be reviewed carefully in the unlikely event that there are conflicts in the merge, because you, or the other developer, may have made customizations to the mapping or entity types which you want to keep.</p>
<p>Finally, it is worth mentioning that <a href="http://blogs.msdn.com/adonet/pages/feature-ctp-walkthrough-code-only-for-the-entity-framework.aspx">the Entity Framework version 4 supports "code only" models</a> which do not use EDMX files at all. If you prefer designing your entity model via source code, you can choose this option.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38542&amp;akst_action=share-this" onclick="akst_share('38542', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F02%2F03%2F38542%2F', 'Entity+Framework+Models+and+Source+Control'); return false;" title="Post to del.icio.us, etc." id="akst_link_38542" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Entity%20Framework%20Models%20and%20Source%20Control&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F02%2F03%2F38542%2F" id="akst_email_38542" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>join in LINQ to SQL and LINQ to Entities Considered Messy, Redundant</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/01/13/38525/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/01/13/38525/#comments</comments>
    <pubDate>Wed, 13 Jan 2010 20:24:20 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38525</guid>
    <description><![CDATA[In this post I will demonstrate that use of the join keyword in LINQ to SQL and LINQ to Entities is nearly always wrong. LINQ queries which you write with the join keyword are harder to read and write than queries you write using associations, and they require knowledge of database metadata which is not [...]]]></description>
      <content:encoded><![CDATA[<p>In this post I will demonstrate that use of the <code>join</code> keyword in LINQ to SQL and LINQ to Entities is nearly always wrong. LINQ queries which you write with the <code>join</code> keyword are harder to read and write than queries you write using associations, and they require knowledge of database metadata which is not required otherwise. This introduces the potential for errors and makes maintenance harder.</p>
<p><a href="http://www.google.com/search?q=left+join+linq">Many people ask how to do a "left join" in LINQ to SQL</a>, and unfortunately, the answer they <a href="http://solidcoding.blogspot.com/2007/12/left-outer-join-in-linq.html">nearly</a> <a href="http://geekswithblogs.net/AzamSharp/archive/2008/04/07/121103.aspx">always</a> <a href="http://stackoverflow.com/questions/1092562/left-join-in-linq">get</a> — "Use <code>DefaultIfEmpty</code>!" — is, in my opinion, terrible advice. Let&#8217;s implement the same query with and without the <code>join</code> keyword, and then compare the readability of the queries, the functionality, the knowledge required to write the query, and the maintainability of the code. I think you will find that using associations wins on every single criterion I examine.</p>
<p>I&#8217;m going to use the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&amp;displaylang=en">Northwind demo database</a> for this example, since many people are familiar with its structure. I created a LINQ to SQL model for Northwind by simply dragging all of the tables in the database onto the LINQ to SQL designer. The only change I made to the model generated by the designer is to rename the "Employee1" property on the generated "Employee" type to the more descriptive name "Supervisor." I&#8217;m using LINQ to SQL for this demo, but everything I&#8217;m saying here applies equally to LINQ to Entities.</p>
<h3>"Left" Joins</h3>
<p>Let&#8217;s imagine that I am asked to produce a web page listing all employees in a company, along with their supervisor, if any. This requires a "left join," in SQL terms, because not all employees have a supervisor. I&#8217;ll project onto a presentation model, <a href="http://blogs.teamb.com/craigstuntz/2009/12/31/38500/">just like I do in LINQ to Entities</a>. Using the association properties generated by LINQ to SQL, this is quite simple:</p>
<p><a href="/files/2010/01/association-left_2275.png"><img src="/files/2010/01/association-left_2275.png" alt="" /></a></p>
<p>This is fairly readable. The one thing that you need to know is that both LINQ to SQL and LINQ to Entities coalesce nulls. This means that on a row where <code>e.Supervisor</code> is null, you will not get a <code>NullReferenceException</code> in the assignment to <code>SupervisorName</code> and <code>SupervisorBirthDate</code>, as you would with LINQ to Objects. Instead, null will be assigned. Therefore, it is important that <code>EmployeeListItem.SupervisorBirthDate</code> is of type <code>DateTime?</code> (a.k.a. <code>Nullable&lt;DateTime&gt;</code>) instead of the non-nullable <code>DateTime</code>.</p>
<p>Let&#8217;s compare that to the equivalent query using the <code>join</code> syntax, using the mysteriously popular<code> DefaultIfEmpty</code> trick:</p>
<p><a href="/files/2010/01/join-left_2278.png"><img src="/files/2010/01/join-left_2278.png" alt="" width="442" height="189" /></a></p>
<p>Yuck! This is far less readable than the query above. Yet these two queries produce <em>exactly the same results</em>. If you don&#8217;t believe me, download the <a href="/files/2010/01/l2sapp_2290.zip">sample project attached to this post</a> and try it yourself. Perhaps even worse than the general unreadability of the "join version" is the fact that this query requires knowledge of the structure of the database which is already present in the DBML (or EDMX, in the case of the Entity Framework) model. This is a problem for two reasons. First, it&#8217;s an opportunity for programmers to make a mistake, which the first query eliminates. Second, it&#8217;s a potential maintenance issue if the foreign key definition ever changes in the database.</p>
<h3>"Inner" Joins</h3>
<p>Now let&#8217;s compare an example of an "inner join" using both my recommended method of associations and the LINQ <code>join</code> keyword. Here&#8217;s the association version. It&#8217;s so readable that there is very little to say about it:</p>
<p><a href="/files/2010/01/association-inner_2281.png"><img src="/files/2010/01/association-inner_2281.png" alt="" width="472" height="152" /></a></p>
<p>Here&#8217;s the <code>join</code> version:</p>
<p><a href="/files/2010/01/join-inner_2287.png"><img src="/files/2010/01/join-inner_2287.png" alt="" width="497" height="184" /></a></p>
<p>Again, these two queries do exactly the same thing, as you can confirm for yourself by running the demo project. The <code>join</code> version here shares all of the faults of the "left join" version above.</p>
<h3>API Consistency</h3>
<p>Thus far, I&#8217;ve been discussing LINQ to SQL. But what if I have an <code>Employee</code> instance and that like to examine the employee&#8217;s supervisor? I might write code like this:</p>
<p><a href="/files/2010/01/supervisor_2291.png"><img src="/files/2010/01/supervisor_2291.png" alt="" width="298" height="15" /></a></p>
<p>Now compare that code with the "association" and "join" query forms. You will see that using the associations makes the LINQ to SQL queries much more closely resemble how you work with the materialized entity objects in "regular" code. Again, I think this makes your code easier to read.</p>
<h3>What About Performance?</h3>
<p>Not surprisingly, the SQL generated by the equivalent association and join versions is close to identical. I would not expect to ever see a performance difference between the two syntaxes in terms of query execution time.</p>
<h3>Is It Ever Correct to Use join?</h3>
<p>The advantages of using associations are so strong that you may wonder why <code>join</code> exists in LINQ at all. Associations, however, are only helpful when they actually exist. There may be times when you need to "join" based on values which are not actually foreign keys. Or you may need to join between LINQ to SQL and LINQ to Objects.</p>
<h3>Running the Demo Project</h3>
<p>Here&#8217;s a <a href="/files/2010/01/l2sapp_2290.zip">the demo project.</a> To build and run it, you&#8217;ll need to Visual Studio 2010 Beta, SQL Server (Express is fine), and the Northwind demo database I linked above. Open the project, find the Web.config file in Solution Explorer and open it. Change the connectionString to point to your SQL Server. Now you should be able to run the application.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38525&amp;akst_action=share-this" onclick="akst_share('38525', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F01%2F13%2F38525%2F', 'join+in+LINQ+to+SQL+and+LINQ+to+Entities+Considered+Messy%2C+Redundant'); return false;" title="Post to del.icio.us, etc." id="akst_link_38525" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=join%20in%20LINQ%20to%20SQL%20and%20LINQ%20to%20Entities%20Considered%20Messy%2C%20Redundant&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F01%2F13%2F38525%2F" id="akst_email_38525" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Crossword No. 2</title>
    <link>http://blogs.teamb.com/craigstuntz/2010/01/11/38518/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2010/01/11/38518/#comments</comments>
    <pubDate>Mon, 11 Jan 2010 19:07:06 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Crosswords]]></category>

		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38518</guid>
    <description><![CDATA[DotNetSlackers just published a crossword puzzle I created; you&#8217;ll see the grid below. The puzzle is focused on .NET and programming themes, including a Delphi reference here and there. The site editors wanted an article to go with the puzzle, so I wrote an article explaining how I created the puzzle. The article is full [...]]]></description>
      <content:encoded><![CDATA[<p>DotNetSlackers just published <a href="http://dotnetslackers.com/articles/net/Creating-a-programming-crossword-puzzle.aspx">a crossword puzzle I created</a>; you&#8217;ll see the grid below. The puzzle is focused on .NET and programming themes, including a Delphi reference here and there. The site editors wanted an article to go with the puzzle, so I wrote an article explaining how I created the puzzle. The article is full of spoilers, so if you&#8217;d like to try and solve the puzzle yourself scroll down to the bottom of the article to find the grid and clues before reading the article at the top.</p>
<p><a href="http://dotnetslackers.com/articles/net/Creating-a-programming-crossword-puzzle.aspx"><img src="/files/2010/01/crossword_2272.jpg" alt="" width="500" height="490" /></a></p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38518&amp;akst_action=share-this" onclick="akst_share('38518', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F01%2F11%2F38518%2F', 'Crossword+No.+2'); return false;" title="Post to del.icio.us, etc." id="akst_link_38518" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Crossword%20No.%202&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2010%2F01%2F11%2F38518%2F" id="akst_email_38518" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Projecting Onto a Presentation Model with the Entity Framework and ASP.NET MVC</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/12/31/38500/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/12/31/38500/#comments</comments>
    <pubDate>Thu, 31 Dec 2009 20:23:59 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38500</guid>
    <description><![CDATA[In this post, I will demonstrate how to map entity models to views in an ASP.NET MVC application without worrying about implementation details like eager loading, lazy loading, or having to manually optimize SQL for the task at hand. I will argue that expressing the relationship between an entity model in the presentation model in [...]]]></description>
      <content:encoded><![CDATA[<p>In this post, I will demonstrate how to map entity models to views in an ASP.NET MVC application without worrying about implementation details like eager loading, lazy loading, or having to manually optimize SQL for the task at hand. I will argue that expressing the relationship between an entity model in the presentation model in a LINQ projection is far simpler than other methods of doing this mapping.</p>
<p>Imagine that you&#8217;ve been asked to write a new web application to track employees for a customer, <a href="http://www.imdb.com/title/tt0151804/quotes">Chotchkies restaurant</a>. The application must use ASP.NET MVC and the ADO.NET Entity Framework. The user interaction designers have mocked up the following interface for editing an employee:</p>
<p><a href="/files/2009/12/employeeeditor_2243.png"><img src="/files/2009/12/employeeeditor_2243.png" alt="Employee editor" width="217" height="283" /></a></p>
<p>Upon seeing this mockup, your first recommendation is to fire the user interface designers. But management declines to follow your recommendation. So how should you implement this? Since this is a new application, you have no database, no entity model, nothing. Where to begin?</p>
<h2>Presentation Models</h2>
<p>For a variety of reasons, I always use strongly-typed views in my ASP.NET MVC applications. Also, I use presentation models instead of using entity types directly as the model type for my views.This allows the user interface and data models to evolve independently.</p>
<p>Because I am likely to want to build user interfaces using ASP.NET MVC 2&#8217;s Dynamic Templated Views, I need to decorate the view model with presentation concerns, like noting that the "Flair count" field is read-only in this particular view.</p>
<p>Especially in view of the less-than-compelling user interface markup, it&#8217;s important to realize that the design of the user interface is likely to change wildly over the course of implementing the application. When actual users begin to test the application, they will request changes to the user interface, and you need to be able to adapt to this.</p>
<p>This has two important implications: You must get a prototype to testers and end-users as fast as possible, and your user interface must not be deeply coupled to the rest of the application, given the high likelihood of change.</p>
<p>So based upon the user interface prototype above, the following presentation model might be reasonable:</p>
<p><a href="/files/2009/12/employeepresentation_2245.png"><img src="/files/2009/12/employeepresentation_2245.png" alt="" /></a></p>
<p>It&#8217;s now trivial to write an action which can be used to develop a view for editing the employee, and which matches the UI prototype above. Such an action might look like:</p>
<p><a href="/files/2009/12/employeeaction_2248.png"><img src="/files/2009/12/employeeaction_2248.png" alt="Demo employee action code" /></a></p>
<p>I&#8217;ll spare you the HTML. At this point, I have a running application which the user interaction designer can approve, and testers can try out. My total effort, thus far, is a few minutes of work. If I had started by designing a database and the data model, I would still have nothing to show for my efforts.</p>
<h2>Entity Model</h2>
<p>At some point however, you need to create a database and an entity model. That was, after all, part of the requirements you were given for the application. Knowing that there might be a need to reference people who are not employees, the entity model is going to have to look very different than the presentation model above. After some discussions with the business analyst, you learn that Chotchkies management is very serious about tracking employee flair, so a first attempt at an entity model might look like this:</p>
<p><a href="/files/2009/12/employeeentities_2254.png"><img src="/files/2009/12/employeeentities_2254.png" alt="" width="500" height="172" /></a></p>
<p>Now you can generate a database. At this point, you have a presentation model and an entity model, and need only wire them together.</p>
<h2>Projection</h2>
<p>Taking a collection of instances of one type, and mapping their properties onto a collection of instances of another type is often called mapping or projection. With older ORMs, which have either no or very limited LINQ support, this can be quite tedious, requiring manual code, the use of tools like AutoMapper, and a good deal of thinking about eager loading, lazy loading, and optimizing situations like the fact that we don&#8217;t actually want to load all of the flair for an employee here; we just need the count.</p>
<p>The Entity Framework, on the other hand, makes this very easy, as we can just express the relationship between the entity model and the presentation model with a LINQ expression:</p>
<p><a href="/files/2009/12/employeeaction_2257.png"><img src="/files/2009/12/employeeaction_2257.png" alt="" width="406" height="236" /></a></p>
<p>I&#8217;m glossing over some details here. In a real-world application, for example, we would use the repository pattern rather than grabbing the context directly in the controller. But the point of this post is shown in the code above:</p>
<p><em>By expressing the relationship between the entity model and the presentation model as a LINQ query, it is no longer necessary to worry about implementation details like eager loading versus lazy loading, optimizing the SQL for the Count and avoiding loading big properties not actually used here. </em>All of this can be — and is — derived from the query above, automatically.<em><br />
</em></p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38500&amp;akst_action=share-this" onclick="akst_share('38500', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F12%2F31%2F38500%2F', 'Projecting+Onto+a+Presentation+Model+with+the+Entity+Framework+and+ASP.NET+MVC'); return false;" title="Post to del.icio.us, etc." id="akst_link_38500" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Projecting%20Onto%20a%20Presentation%20Model%20with%20the%20Entity%20Framework%20and%20ASP.NET%20MVC&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F12%2F31%2F38500%2F" id="akst_email_38500" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Delphi Developers: Go Buy CodeHealer</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/12/22/38495/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/12/22/38495/#comments</comments>
    <pubDate>Tue, 22 Dec 2009 11:56:00 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Uncategorized]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38495</guid>
    <description><![CDATA[If you&#8217;re doing commercial Delphi development and you&#8217;re not already doing static analysis in your automated build, go buy CodeHealer now. Nick Hodges has arranged a 1/2 price special offer.
There is no good reason not to use static analysis. If you are the sort of person who doesn&#8217;t allow hints and warnings in your code, [...]]]></description>
      <content:encoded><![CDATA[<p>If you&#8217;re doing commercial Delphi development and you&#8217;re not already doing static analysis in your automated build, go buy CodeHealer now. <a href="http://blogs.embarcadero.com/nickhodges/2009/12/21/39340">Nick Hodges has arranged a 1/2 price special offer</a>.</p>
<p>There is <em>no</em> good reason not to use static analysis. If you are the sort of person who doesn&#8217;t allow hints and warnings in your code, and has configured your build to fail on any hint or warning (and I hope that you are), then you&#8217;ll love static analysis; it takes this kind of discipline to the next level. Sure, it&#8217;s useful to find existing errors in your code, but the most important benefit is that it prevents new errors from being introduced.</p>
<p>The only remotely valid argument I&#8217;ve heard against using static analysis is that when you first use a static analysis tool against a legacy code base, you will typically see hundreds of rules violations, many of them incorrect. Cleaning all this up will be a lot of work, which you usually can&#8217;t take on all at once.</p>
<p>Unlike compiler hints and warnings, static analysis rule violations often happen when there is no underlying bug. When you develop new code, you can analyze any newly introduced rule violation and exclude it if necessary. But that&#8217;s not practical to do with legacy code. My approach to this problem is very simple: Turn off rules in your static analysis tool until all the rule violations go away.</p>
<p>What&#8217;s the point of buying a static analysis tool and then turning off half the rules? Well, the other half are still turned on, and they are now a part of your automated build, making it impossible to introduce new code which violates them. Moreover, you can go back and turn on the other rules a reasonable pace, say, one or two a week, fixing real issues that you find or excluding the particular violation if it turns out to be a non-issue, until they are all turned back on.</p>
<p>Once you have even a few static analysis rules turned on in your automated build, you&#8217;re getting some degree of quality control for very little expense. Integration testing costs money, every time you do it. Unit testing costs money every time you write new tests. Static analysis just works and keeps working, and costs you nothing more than a software upgrade once every couple years or so.</p>
<p>So static analysis in general is a good thing. What about CodeHealer in particular? Well, we have been using it for around three years now. It has been stable, and I&#8217;ve seen new versions released regularly. Also, I have never seen anything better for Delphi.</p>
<h4>Digression: Attributes</h4>
<p>When Delphi 2010 was released with the enhanced RTTI and custom attributes feature, many Delphi developers wondered what this feature would be useful for. In general, your source code describes the behavior of your application, and attributes describe your mechanisms (thanks to Eric Lippert for this concise description). Static analysis is an excellent example. Imagine that I want to exclude a static analysis rule in a particular case. This has nothing to do with the desired functionality of the application; rather, it&#8217;s more like a parameter to the automated build process.</p>
<p>That may sound a bit abstract, so let&#8217;s look at a specific example. FxCop, a static analysis tool for .NET code, has rule that should not introduce private types which are never used. But FxCop cannot detect the instantiation of types inside of a LINQ query. So in this case the rule is making a mistake; it is failing to detect that a type is, in fact, instantiated in my code. One possible solution to this issue would be to try and write a better rule. But that&#8217;s a lot of work, and there are only about two cases of this false positive in our entire source tree. So it&#8217;s easier to just suppress this message in the case of a false positive, which you can do with an attribute:</p>
<blockquote>
<pre><code>[System.Diagnostics.CodeAnalysis.SuppressMessage(
    "Microsoft.Performance",
    "CA1812:AvoidUninstantiatedInternalClasses",
    Justification = "It is instantiated in a query, which FxCop can't see.")]
<strong>private class </strong>ConsumerRow //...</code></pre>
</blockquote>
<p>This is far easier (and, I think, a better design) than what CodeHealer currently offers. I hope that future versions of CodeHealer will use this method, now that Delphi has attribute support.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38495&amp;akst_action=share-this" onclick="akst_share('38495', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F12%2F22%2F38495%2F', 'Delphi+Developers%3A+Go+Buy+CodeHealer'); return false;" title="Post to del.icio.us, etc." id="akst_link_38495" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Delphi%20Developers%3A%20Go%20Buy%20CodeHealer&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F12%2F22%2F38495%2F" id="akst_email_38495" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Interview With Me At Delphi.org</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/10/21/38492/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/10/21/38492/#comments</comments>
    <pubDate>Wed, 21 Oct 2009 12:35:39 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Delphi]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38492</guid>
    <description><![CDATA[Jim McKeeth interviewed me for Episode 34 of The Podcast At Delphi.org.
]]></description>
      <content:encoded><![CDATA[<p>Jim McKeeth interviewed me for <a title="34 – Craig Stuntz" href="http://www.delphi.org/2009/10/34-craig-stuntz/">Episode 34 of The Podcast At Delphi.org</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38492&amp;akst_action=share-this" onclick="akst_share('38492', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F21%2F38492%2F', 'Interview+With+Me+At+Delphi.org'); return false;" title="Post to del.icio.us, etc." id="akst_link_38492" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Interview%20With%20Me%20At%20Delphi.org&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F21%2F38492%2F" id="akst_email_38492" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Updating to ASP.NET MVC 2 Preview 2</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/10/05/38476/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/10/05/38476/#comments</comments>
    <pubDate>Mon, 05 Oct 2009 19:35:16 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38476</guid>
    <description><![CDATA[Last week, I updated our main development branch to ASP.NET MVC 2 preview 2 (from preview 1). In this post, I&#8217;ll list some of the features I&#8217;ve found, and also issues I encountered and how I resolved them.
New Features
Some of the new features of preview 2 have been discussed elsewhere, so I won&#8217;t rehash them. [...]]]></description>
      <content:encoded><![CDATA[<p>Last week, I updated our main development branch to ASP.NET MVC 2 preview 2 (from preview 1). In this post, I&#8217;ll list some of the features I&#8217;ve found, and also issues I encountered and how I resolved them.</p>
<h3>New Features</h3>
<p>Some of the new features of preview 2 have been discussed elsewhere, so I won&#8217;t rehash them. But I&#8217;ve also noticed that there is a new attribute, <code>[RequireHttps]</code>, which does what you would expect, when added to an action, and a new HTML helper, <code>Html.HttpMethodOverride</code>, which makes it easy to take a POST request and code as if the request were actually PUT or DELETE, by adding a hidden input containing a special value on the HTML form. This allows you to write your server in a more RESTful style, which will be suitable for user agents which know about the PUT and DELETE verbs, while maintaining compatibility with those (like browsers) which do not.</p>
<h3>MvcHtmlString</h3>
<p>After installing the new assembly into the GAC, I attempted to compile our existing projects. I got a compilation error on some of our custom HTML helpers, as the MVC extension methods like <code>Html.RouteLink</code> have been changed to return an instance of type <code>MvcHtmlString</code> instead of <code>String</code>. In many cases, I could just change the return type. However, the clear intention of the framework designers is that any HTML helpers which return HTML (with angle brackets) instead of "plain" text should return a <code>MvcHtmlString</code> instead of a <code>String</code>. So, in addition to changing the return types of methods where necessary to get those methods to compile, I also wanted to change the return types of any custom HTML helper which returned HTML containing angle brackets. It makes no difference today, but <a href="http://haacked.com/archive/2009/09/25/html-encoding-code-nuggets.aspx">in ASP.NET 4, there will be a new syntax to guard against XSS attacks</a>, and it makes sense to get ready for this by returning the correct type.</p>
<p>The trick here is that <code>MvcHtmlString</code> does not have a public constructor, so it&#8217;s not immediately obvious how to create one of these things. Perusing the MVC source code, I noticed that it does have a static <code>Create</code> method, and comments elsewhere in the source code indicate that this method should be used instead of the detected constructor. So you can now write a helper like this:</p>
<blockquote>
<pre><code><strong>public static</strong> MvcHtmlString Fud(<strong>this </strong>HtmlHelper helper)
{
    <strong>return </strong>MvcHtmlString.Create("&lt;acronym title=\"Fear, Uncertainty, and Doubt\"&gt;FUD&lt;/acronym&gt;");
}
</code></pre>
</blockquote>
<h3>JsonRequestBehavior</h3>
<p>ASP.NET MVC will now, by default, throw an exception when an action attempts to return JSON in response to a GET request. Unless you read the release notes carefully, you won&#8217;t discover this until runtime. This is in order to proactively defend against <a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx">a particular cross-site attack</a>. It is good to be safe by default, but you are only vulnerable to this attack under the following combination of circumstances:</p>
<ul>
<li>The data you&#8217;re returning is worth stealing.</li>
<li>The root data object in the JSON response is an array.</li>
<li>The requesting browser is not IE 8, or some other browser which doesn&#8217;t allow <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Object/DefineSetter"><code>__defineSetter__</code></a></li>
</ul>
<p>It turns out that in our application we almost never return JSON results with the root object as an array in a GET. So the best fix was generally just to tell the framework that we have examined the risk and determined it returning JSON in this case, by changing code like:</p>
<blockquote><p><code><strong>return </strong>Json(model);</code></p></blockquote>
<p>&#8230;to:</p>
<blockquote><p><code><strong>return </strong>Json(model, JsonRequestBehavior.AllowGet);</code></p></blockquote>
<p>Unfortunately, I had to make this change in a lot of places. Still, I agree with the framework designers: Better safe than sorry.</p>
<h3>JavaScript Files</h3>
<p>The MicrosoftAjax.js, MicrosoftAjax.debug.js, MicrosoftMvcAjax.debug.js, and MicrosoftMvcAjax.debug.js files have all changed for ASP.NET MVC 2. Existing ASP.NET MVC 1.0 projects will have old versions of these files. <del datetime="00">The upgrade instructions in the Release Notes don&#8217;t mention this, but</del> (they do; I just missed it) you should replace these files with the newer versions when upgrading to MVC 2. To do this, create a new MVC 2 project, copy the JavaScript files from the Scripts folder in this new project, and paste them over the existing files in the project you are upgrading.</p>
<h3>ModelBindingContext Changes</h3>
<p>One of the new features of preview 2 is client-side validation and custom metadata providers for validations. In order to implement this feature, some of the implementation details of model binding have changed. This won&#8217;t affect most people, but the fix was a little tricky, and required a good bit of examination of the MVC source code, so I&#8217;ll list it anyway. Prior to preview 2, I had code in a unit test for a custom model binder like this:</p>
<blockquote>
<pre><code>        <strong>internal static </strong>T Bind&lt;T&gt;(<strong>string </strong>prefix, FormCollection collection, ModelStateDictionary modelState) <strong>where </strong>T:<strong>class</strong>
        {
            <strong>var </strong>mbc = <strong>new </strong>ModelBindingContext()
            {
                ModelName = prefix,
                ModelState = modelState,
                ModelType = typeof(T),
                ValueProvider = collection.ToValueProvider()
            };
            IModelBinder binder = <strong>new </strong>MyModelBinder();
            <strong>var </strong>cc = <strong>new </strong>ControllerContext();
            <strong>return </strong>binder.BindModel(cc, mbc) <strong>as </strong>T;
        }
</code></pre>
</blockquote>
<p>With Preview 2, on the other hand, I have to do this:</p>
<blockquote>
<pre><code>        <strong>internal static </strong>T Bind&lt;T&gt;(<strong>string </strong>prefix, FormCollection collection, ModelStateDictionary modelState) <strong>where </strong>T:<strong>class</strong>
        {
            <strong>var </strong>mbc = <strong>new </strong>ModelBindingContext()
            {
                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(T)),
                ModelName = prefix,
                ModelState = modelState,
                ValueProvider = collection.ToValueProvider()
            };
            IModelBinder binder = <strong>new </strong>MyModelBinder();
            <strong>var </strong>cc = <strong>new </strong>ControllerContext();
            <strong>return </strong>binder.BindModel(cc, mbc) <strong>as </strong>T;
        }
</code></pre>
</blockquote>
<p>Not hard once you know the trick.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38476&amp;akst_action=share-this" onclick="akst_share('38476', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F05%2F38476%2F', 'Updating+to+ASP.NET+MVC+2+Preview+2'); return false;" title="Post to del.icio.us, etc." id="akst_link_38476" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Updating%20to%20ASP.NET%20MVC%202%20Preview%202&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F05%2F38476%2F" id="akst_email_38476" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Comparing C#, C++, and Delphi (Win32) Generics</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/10/01/38465/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/10/01/38465/#comments</comments>
    <pubDate>Thu, 01 Oct 2009 19:13:29 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Delphi]]></category>

		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38465</guid>
    <description><![CDATA[C#, C++, and Delphi all have a generic type and method language feature. Although all three languages are statically typed, they implement generics in very different ways. I&#8217;m going to give a brief overview of the differences, both in terms of language features and implementation. I presume that Delphi Prism generics work essentially the same [...]]]></description>
      <content:encoded><![CDATA[<p>C#, C++, and Delphi all have a generic type and method language feature. Although all three languages are statically typed, they implement generics in very different ways. I&#8217;m going to give a brief overview of the differences, both in terms of language features and implementation. I presume that Delphi Prism generics work essentially the same as C# generics, which, as you’ll see, is different than Delphi/Win32 generics.</p>
<p>Let me say at the outset that although all three systems work somewhat differently, I don&#8217;t see an overwhelming advantage to any one design. Generally, you can do what you need to do in all three environments. I&#8217;m writing this article not to claim that any one system is better than the others, but to point out some of the subtleties in the implementations.</p>
<p>Before I get started, I&#8217;d like to thank <a href="http://blog.barrkel.com/">Barry Kelly</a> for his useful feedback on my first draft of this article.</p>
<h3>Compiling Instantiations</h3>
<p>Every implementation of generic types works via a two-step process. First, you define a generic type or method with a "placeholder" for a specific type, which will be substituted later on. Later (exactly when depends upon the language), the type is "instantiated." Note that instantiating a generic type is very different from instantiating an object. The former happens within the compiler, whereas the latter happens at runtime.</p>
<p>Instantiation is triggered when some code uses a generic type or method with a specific type parameter, and means that based upon the generic definition and the types or values passed when the generic is used, a specific implementation is substituted in order to allow the generation of machine code. Instantiation is one of the most important differences between real generic types and using non-generic types with casts. In the end, different machine code is generated for instantiations for different type parameters.</p>
<p>In C# and Delphi, there is a language feature which is solely dedicated to implementing generic types and methods. In C++, on the other hand, the "templates" language feature can be used to implement generic types and methods, among many, many other things. It is even possible to do general-purpose programming using templates, which C++ programmers call "<a href="http://www.codeproject.com/KB/cpp/crc_meta.aspx">metaprogramming</a>."</p>
<p>C++ templates require the template source code to be available when the code using the template is compiled. This is because the compiler does not actually compile the template as a separate entity, but rather instantiates it "in-place" and only compiles the instantiation. The C++ compiler is effectively doing code generation, substituting the type parameter (or value) for the placeholder for the type, and generating new code for the instantiation. <strong>Update:</strong> <a title="Audacia Software" href="http://www.audacia-software.de/">Moritz Beutel</a> elaborates on this in <a href="http://blogs.teamb.com/craigstuntz/2009/10/01/38465/#comment-9937">his excellent comment on this post</a>. You should read the full comment, but the short version is that the manner in which templates are compiled can result in errors in the code which uses the template appearing (from compiler error messages), incorrectly, to be errors in the template itself. Moreover, the implementation of most C++ compilers makes this problem even worse than what is necessary in order to implement the C++ standard.</p>
<p>In Delphi and C#, on the other hand, the generic type or method in the code which uses the generic type or method can be compiled separately. Therefore, you can compile a library which contains a generic type, and later on compile an executable which uses a instantiation of that type and has a reference to the binary library, rather than to the source code for the library.</p>
<p>Another way to think of this difference is that in C++, a template will not be compiled at all until it is used. In Delphi and C#, on the other hand, a generic type or method <em>must </em>be compiled before it can be used.</p>
<p>In Delphi, the compiler uses a feature closely related to the method inlining feature. This causes the compiler to store the relevant bits of the abstract syntax tree for the generic type parameter in the compiled DCU. When the code which uses the generic type is compiled, this bit of the abstract syntax tree is read and included in the abstract syntax tree for the code which uses the generic type, so that when machine code is produced, based on the new, “compound” abstract syntax tree, it looks, to the code emitter, like the type was defined with the type parameter "hard coded." Instead of linking to compiled code in the DCU, the code which uses the generic type emits new code for the instantiation into its own DCU.</p>
<p>Because generic instantiation is performed in the same area of the Delphi compiler which does method inlining, there are some limitations on what you can do in a generic method, or a method of a generic type. Like inlined methods, these methods cannot contain ASM. Also, calls to these methods cannot be inlined. These restrictions are limitations of the implementation, not of the language design, and could theoretically be removed in a future version of the compiler.</p>
<p>C# generics use the .NET Framework 2.0+, which has native support for generic types. The C# compiler emits IL which specifies that a generic type should be used, with certain type parameters. The .NET framework implements these types using one instantiation for <em>any </em>reference type, and custom instantiations for value types. (Don’t confuse “instantiation” with “instance” in the preceding sentence; they mean entirely different things in this context. There are usually many instances of one instantiation.) This is because a reference to a reference type is always the same size, whereas value types can be many different sizes. Later, the IL will be JITted into machine code, and, as with compiled C++ or Delphi code, types don’t really exist at the machine code level. In .NET, generic type instantiation and JITting are two distinct operations.</p>
<p>So one important difference in generics implementations is when the instantiation occurs. It occurs very early in C++ compilation, somewhat later for Delphi compilation, and as late as possible for .NET compilation.</p>
<h3>Custom Specializations</h3>
<p>Another very important difference is that C++ allows custom instantiations, called specializations, including specializations by value. With C# and Delphi, on the other hand, the only way to instantiate a generic type is to use that type with an explicit type parameter. The implementation will always be the same, with the exception of the type of the type parameter. Because C++ allows custom instantiations, it is easy for a programmer to write different implementations of a method, for example, for different integer values. Like operator overloading, this is a powerful feature which requires considerable self-restraint to avoid abuse.</p>
<h3>Constraints</h3>
<p>Delphi and C# both have a generic constraint feature, which allows/requires the developer of a generic or method type to limit which type parameter values can be passed. For example, a generic type which needs to iterate over some list of data could require that the type parameter support <code>IEnumerable</code>, in either language. This allows the developer of the generic type to make her intentions for the use of the type very clear. It also allows the IDE to provide code completion/IntelliSense on the type parameter, within the definition of the generic type. Also, it allows a user of the generic type to be confident that they are passing a legal value for the type parameter without having to compile their code to find out.</p>
<p>In C++, on the other hand, there is not presently any such feature. <a href="http://www.devx.com/cplus/Article/42365">A more powerful/complex feature called "concepts" was considered for, but ultimately removed from, C++0x</a>.</p>
<p>An implication of the lack of constraints is that <a href="http://www.ddj.com/cpp/184401971">C++ templates are duck typed</a>. If a generic method calls some method, <code>Foo</code> on a type passed as the generic type parameter, then the template is going to compile just fine so long as the type parameter passed contains some method called <code>Foo</code> with the appropriate signature, no matter where or how it is defined.</p>
<h3>Covariance and Contravariance</h3>
<p>Let’s say I have a function which takes an argument of type <code>IEnumerable&lt;TParent&gt;</code>. Can I pass an argument of type <code>IEnumerable&lt;TChild&gt;</code>; to that function? What if the argument type were <code>List&lt;TParent&gt;</code>; instead of <code>IEnumerable&lt;TParent&gt;</code>? Or what if the generic type was the function <em>result </em>rather than the function argument? The formal names for these problems are <a href="http://blog.barrkel.com/2006/07/covariance-and-contravariance-in-net.html">covariance and contravariance</a>. The precise details are too complicated to explain in this article, but the examples above summarize the most common times you run into the problem.</p>
<p>Delphi generics and C++ templates do not support covariance and contravariance. So the answers to the questions above are no, no, and no, although there are, of course, workarounds, like copying the data into a new list. <a href="http://visualstudiomagazine.com/articles/2009/05/01/generic-covariance-and-contravariance-in-c-40.aspx">In C# 4.0, function arguments and results can be declared covariant or contravariant</a>, so the examples above can be made to work where appropriate. "Where appropriate" involves non-trivial subtleties hinted at above, and exemplified by the fact that <a href="http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx">arrays in .NET have (intentionally) broken covariance</a>. However, the <a href="http://msdn.microsoft.com/en-us/library/dd799517%28VS.100%29.aspx">BCL routines in the .NET Framework 4.0 have been annotated to support covariance and contravariance when appropriate</a>, so developers will benefit from the feature without having to fully understand it.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38465&amp;akst_action=share-this" onclick="akst_share('38465', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F01%2F38465%2F', 'Comparing+C%23%2C+C%2B%2B%2C+and+Delphi+%28Win32%29+Generics'); return false;" title="Post to del.icio.us, etc." id="akst_link_38465" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Comparing%20C%23%2C%20C%2B%2B%2C%20and%20Delphi%20%28Win32%29%20Generics&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F10%2F01%2F38465%2F" id="akst_email_38465" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>NDepend Review and Tips</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/24/38398/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/24/38398/#comments</comments>
    <pubDate>Thu, 24 Sep 2009 19:41:30 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38398</guid>
    <description><![CDATA[On and off for the past few months, I&#8217;ve been experimenting with the .NET static analysis tool NDepend. NDepend works somewhat differently than most other static analysis tools I&#8217;ve tried. Notably,

Most tools tend to work on either compiled assemblies or source code. NDepend uses both.
Most tools implement their tests in compiled, executable code. NDepend, on [...]]]></description>
      <content:encoded><![CDATA[<p>On and off for the past few months, I&#8217;ve been experimenting with the .NET static analysis tool NDepend. NDepend works somewhat differently than most other static analysis tools I&#8217;ve tried. Notably,</p>
<ul>
<li>Most tools tend to work on either compiled assemblies or source code. NDepend uses both.</li>
<li>Most tools implement their tests in compiled, executable code. NDepend, on the other hand, uses a proprietary, domain-specific language called CQL.</li>
<li>NDepend can enhance its analysis by importing analysis data from related builds, like NCover, Team System coverage analysis, and can compare multiple builds of the same project.</li>
</ul>
<p>As with other static analysis tools, however, NDepend is designed to be used both within Visual Studio and as part of an automated build/continuous integration process.</p>
<p>NDepend claims to support "<a href="http://www.ndepend.com/FAQ.aspx">any .NET language including C#, VB.NET, MC++ and C++\CLI</a>." To put this claim to the test, I ran it against <a href="http://cc.embarcadero.com/Item/26978">a Delphi Prism application</a>. Indeed, it did produce useful results in the analysis, although there were some quirks. It couldn&#8217;t find the assembly from the solution, but after I located it manually analysis could run. I suspect NDepend doesn&#8217;t parse the source code of Prism applications as it does with C#.</p>
<h3>What NDepend Does</h3>
<p>The name "NDepend" presumably comes from the dependency analysis feature. NDepend will display dependencies between assemblies either as a cross tab or a directed graph. See the website for illustrations of this feature.</p>
<p>NDepend also does static analysis along the same lines as Microsoft FxCop and StyleCop, only in a much more interactive manner. By combining the features I&#8217;ve already mentioned, you can easily ask queries like, "What are the most complex methods I&#8217;ve changed recently which have no unit test coverage?"</p>
<p>All of NDepend&#8217;s features are available in its own GUI application, from the command line, within Visual Studio, and in a custom MS build task. So, as with most static analysis tools, you can integrate NDepend into a continuous build environment in order to set enforceable standards on code complexity and the like.</p>
<h3>Installation</h3>
<p>NDepend does not have an installer. You need to create a folder for the application, and unzip an archive file into that folder. To install the integration with Visual Studio, you click a button in the GUI application, once it&#8217;s running. I find point and click installers a bit more convenient, but it was certainly easy to get the application working.</p>
<h3>Default Analysis of a Do-Nothing Application</h3>
<p>NDepend is quite strict even in its default configuration. For example, I ran it on a do-nothing, "File-&gt;New" ASP.NET MVC 2 Preview 1 application, with no code of my own added. It reported quite a number of warnings.</p>
<p>Many of the warnings were incorrect, because NDepend did not automatically find the System.Web.Mvc assembly, which is not stored along with the rest of the .NET framework, even though it is in the GAC. In general, the current version of NDepend will only find assemblies which are in the solution folder or are in the .NET Framework folders automatically. You should add other folders for referenced assemblies manually, even if those assemblies are GACced. To fix this, I had to do the following steps:</p>
<ol>
<li>Go to the Project Properties tab in the GUI.</li>
<li>Click the "View Folders" button.</li>
<li>Click the "Browse" button and manually locate the folder containing the required assembly.</li>
</ol>
<p>With these steps completed, the quality of the analysis improved quite a lot.</p>
<p>NDepend shows the results in its GUI and also produces an HTML report. The HTML report for the do-nothing application was 14 pages long, and the report for our production web application ran over 50 pages. This can be kind of overwhelming for a new user. The issues flagged in the do-nothing application included (with my comments in parentheses):</p>
<ul>
<li>Methods with &gt; 10 lines of code should be commented. (I disagree; methods should be commented when their intention cannot be made clear in code. This has little relationship to method length and is difficult to impossible to flag with static analysis.)</li>
<li>Types with no state should probably be static. (Worth considering.)</li>
<li>Types with no subtypes could be sealed. (NDepend makes it easy to turn this off for public types.)</li>
<li>Classes with small instance sizes, etc., could be structs. (Maybe, if you want value semantics.)</li>
<li>Avoid namespaces with few types. (This is expected on a File-&gt;New application; would work better in a "real" app. FxCop has the same rule.)</li>
<li>You should&#8217;t have types outside a declared namespace. (I agree.)</li>
<li>Avoid [un] boxing. (I agree; great test!)</li>
<li>Types which "could be internal." (NDepend can&#8217;t pick up instantiation via reflection, making this less useful in the specific case of MVC.)</li>
<li>Fields which are assigned only by the constructors of their types should be marked read-only. (I agree; this is a really useful test.)</li>
<li>Type names should begin with an uppercase letter. The default MVC application includes a type called "_Default".</li>
</ul>
<p>For the sake of comparison, I analyzed the same application using FxCop. This produced 11 warnings, about half correct, and about half incorrect. Incorrect warnings included not recognizing the <acronym title="Three Letter Acronym">TLA</acronym> MVC, asserting that Application_Start should be static, and claiming that the application should target .NET Framework 3.5 SP 1 (as opposed to just 3.5), something which Visual Studio 2008 does not allow. Probably correct warnings included that the application should have the CLSCompliant attribute, and that the _Default type was oddly named.</p>
<h3>Customizing the Analysis For a Real Application</h3>
<p>NDepend&#8217;s use of its CQL language to implement its test makes individual test very easy to customize. For example, our production web application includes the Microsoft DynamicQuery library, which is distributed as a single CS file. Because we included this in one of our assemblies instead of creating a separate assembly for it, NDepend analyzes it along with the rest of our assembly. It contains many long methods, and other things which NDepend does not like, but because this is Microsoft&#8217;s code, and not ours, I would like exclude it from the analysis. So I can, for example, change the test for "method too long" from:</p>
<blockquote>
<pre><span style="color: #008000">// &lt;Name&gt;</span><strong>Methods too big (NbLinesOfCode)</strong><span style="color: #008000">&lt;/Name&gt;
</span><span style="color: #0000ff">WARN</span> <span style="color: #0000ff">IF</span> <span style="color: #000064">Count</span> <span style="color: #000000">&gt;</span> <strong>0</strong> <span style="color: #0000ff">IN</span> <span style="color: #0000ff">SELECT</span> <span style="color: #0000ff">TOP</span> <strong>10</strong> <span style="color: #0000ff">METHODS</span> <span style="color: #0000ff">WHERE</span> <span style="color: #000064">NbLinesOfCode</span> <span style="color: #000000">&gt;</span> <strong>30</strong> <span style="color: #0000ff">ORDER</span> <span style="color: #0000ff">BY</span> <span style="color: #000064">NbLinesOfCode</span> <span style="color: #0000ff">DESC</span><span style="color: #000000">
</span><span style="color: #008000">// METHODS WHERE NbLinesOfCode &gt; 30 are extremely complex and
</span><span style="color: #008000">// should be split in smaller methods
</span><span style="color: #008000">// (except if they are automatically generated by a tool).
</span><span style="color: #008000">// See the definition of the NbLinesOfCode metric here </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCode">http://www.ndepend.com/Metrics.aspx#NbLinesOfCode</a></span></pre>
<p>to:</p>
<pre><span style="color: #0000ff">WARN</span> <span style="color: #0000ff">IF</span> <span style="color: #000064">Count</span> <span style="color: #000000">&gt;</span> <strong>0</strong> <span style="color: #0000ff">IN</span> <span style="color: #0000ff">SELECT</span> <span style="color: #0000ff">TOP</span> <strong>10</strong> <span style="color: #0000ff">METHODS</span>
    <span style="color: #0000ff">WHERE</span> <span style="color: #000064">NbLinesOfCode</span> <span style="color: #000000">&gt;</span> <strong>30</strong>
        <span style="color: #0000ff">AND</span> <span style="color: #000000">!</span><span style="color: #000000">(</span><span style="color: #000064">FullNameLike</span> <span style="color: #a31515">"^System.Linq.Dynamic"</span><span style="color: #000000">)</span> <span style="color: #0000ff">
    ORDER</span> <span style="color: #0000ff">BY</span> <span style="color: #000064">NbLinesOfCode</span> <span style="color: #0000ff">DESC</span></pre>
</blockquote>
<p>What if you don&#8217;t know how to write a regular expression? Well, then you need to <a href="http://www.regular-expressions.info/quickstart.html">learn how to write a regular expression</a>. Regular expressions are the only option for this kind of name matching in NDepend.</p>
<p>It might seem at first that using a proprietary language would be a barrier to using the tool. After all, other tools, like FxCop can be customized using C# and other .NET languages. Doesn&#8217;t a proprietary syntax like CQL discourage customization? Not really, in my experience. The real win of NDepend is that you can customize the rules interactively, within the GUI. In contrast to building a custom FxCop rule and restarting FxCop, this is a huge win, because it encourages the use of ad hoc queries and trial and error to build the ideal heuristic for your application. Coupled with auto complete in the CQL editor, it makes the relatively minor inconvenience of dealing with a proprietary language almost irrelevant. Yes, I would prefer to use LINQ, but the interactivity of CQL is a much bigger win.</p>
<p>However, you don&#8217;t get the same kind of customizability at a global level. You can include and exclude assemblies from analysis globally, but that&#8217;s about it. So while you can include and exclude code based on almost any imaginable criterion at the level of an individual test, I have not found any way to do an exclusion like the one I demonstrate above globally. (Note, however, that in a comment on this blog a week ago, <a href="http://blogs.teamb.com/craigstuntz/2009/09/16/38396/#comments">a member of the NDepend team suggested that features along this line may be coming next year</a>.)</p>
<p>I should add that most static analysis tools seem to work this way. They typically make it fairly easy to include and exclude entire tests or specific tests on specific cases, but don&#8217;t typically include a way to say, "Don&#8217;t run any test on any bit of code which meets the following criteria, ever." So NDepend is no worse than other tools I&#8217;ve used in this regard, and it&#8217;s features to customize individual tests are considerably better than most other tools, although the learning curve is a bit steeper.</p>
<p>Like every static analysis tool I&#8217;ve ever tried, NDepend does not produce useful results for generated code. Since this is not an NDepend-specific issue, I discussed it in <a title="Static Analysis and Generated Code" href="http://blogs.teamb.com/craigstuntz/2009/09/16/38396/">an earlier post</a>, along with some tips for excluding generated code from NDepend&#8217;s analysis.</p>
<h3>Documentation</h3>
<p>The documentation in the NDepend online help is a bit thin. But the authors have written <a title="NDepend Tips and Tricks" href="http://www.ndepend.com/Tips.aspx">a number of informative blog posts</a> on how to use specific features and tips for getting the most out of the tool. Once you realize that these posts exist and know where to find them, it is quite a bit easier to read up on how to use the tool effectively.</p>
<h3>Usability</h3>
<p>I&#8217;m of two, contrasting opinions regarding the usability of NDepend. I found the initial learning curve to be quite steep, and elements of the user interface to be not very discoverable. On the other hand, once I figured out how to use the application, which took me a few weeks (maybe I&#8217;m just slow), I found the application to be very usable, and I could do what I needed to do very quickly. Watching the <a href="http://www.ndepend.com/VisualNDepend.aspx">videos on the NDepend website</a> helps quite a lot in getting over this initial hump. I&#8217;ve also had some e-mail discussions with the makers of the software on how they might improve some of the things this new user found initially confusing in their next release.</p>
<p>For those new to the application, here are some things which may help you get started:</p>
<ul>
<li>The CQL query editor has auto complete, so it&#8217;s fairly easy to customize a query even if you&#8217;re unfamiliar with the language. However, if you intend to do any serious work in CQL, it is worth seeking out and spending some time reviewing the <a href="http://www.ndepend.com/CQL.htm#_Toc225919999">CQL examples on the NDepend website</a>.</li>
<li>After you do an initial analysis, look at the error list before considering the analysis results. Adjust the configuration (by adding assemblies or search directories) to clean up any of the errors before moving on to looking at the analysis results. There are a few valid C# language constructs that NDepend&#8217;s source code parser won&#8217;t recognize. I got a warning from a class constraint on a generic type. I understand this will be fixed in a future version. You can ignore these warnings; they&#8217;re harmless.</li>
<li>Whatever you want to do within the application, the place to start is by selecting the appropriate view configuration from the View menu. So if you want to alter a query to return more specific results, you would select View -&gt; Reset Views to work with the CQL language.</li>
<li>The CQL Query Result tab will display a query, and has been Edit button, you can never added a query in that window. To edit a query, go to the CQL Queries tab, select the query you&#8217;d like to edit, and click the Edit Query button. A new tab will appear which allows you to actually edit query.</li>
<li>When you click on a query in the CQL Queries window, you will only see the results if the query returns any rows. If the query returns no rows, then the results window will not appear.</li>
<li>Whenever you analyze the project in the NDepend GUI, NDepend creates a lengthy HTML report, and opens it in your web browser. But all of the information in the report is also available within the GUI application, as well. So you can see the same information in whichever place is most convenient for you to navigate.</li>
</ul>
<h3>Performance</h3>
<p>NDepend is fast, sometimes surprisingly so, given that it is looking at both binaries and source code. It generally takes less time to run an analysis than it does to compile a solution. I never experienced any performance problems in the NDepend GUI, either.</p>
<h3>Conclusion</h3>
<p>Do you need NDepend? It depends. NDepend will be useful to developers and teams who have a functioning continuous integration process (<a href="http://blogs.teamb.com/craigstuntz/2007/10/30/37765/">and you should</a>) and want to impose standards on this sort of code which can be checked in to the repository. But if you&#8217;re going to go down this road, you should probably start with FxCop, which is free and better known. NDepend, however, can take this kind of analysis much, much farther than would be possible even with custom FxCop rules, like comparing multiple versions of an application and mandating unit test coverage. I also find it much easier to customize.</p>
<p>If you do have an automated build procedure in place and you&#8217;re not already doing static analysis, it&#8217;s time to start! It can be a bit overwhelming to run static analysis for the first time on a legacy project and see hundreds of warnings or errors. But that&#8217;s easy to get over; simply disable all the warnings but one, and start cleaning things up a bit at a time. You can make the analysis stricter as time goes on. You don&#8217;t have to start by fixing everything. Even a few rules in place will prevent new such errors being introduced to the source base.</p>
<p>It will be also useful to developers confronting a large source base for the first time, particularly if there are more than a few assemblies involved.</p>
<p>While NDepend might be useful to a single developer reviewing their own code, and not part of an automated process, I&#8217;ve found that static analysis will really only be used regularly when it is automated. Few developers have the discipline to run static analysis and cleanup any problems uncovered without integrating it into build automation.</p>
<h3>Disclaimer</h3>
<p>This review is based on a review copy supplied by the makers of NDepend. If you think that has colored my impressions of the tool, well, I disagree, but at least you know.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38398&amp;akst_action=share-this" onclick="akst_share('38398', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F24%2F38398%2F', 'NDepend+Review+and+Tips'); return false;" title="Post to del.icio.us, etc." id="akst_link_38398" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=NDepend%20Review%20and%20Tips&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F24%2F38398%2F" id="akst_email_38398" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>The Leadership Mistake I Keep Making</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/22/38447/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/22/38447/#comments</comments>
    <pubDate>Tue, 22 Sep 2009 19:24:28 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38447</guid>
    <description><![CDATA[I need to teach myself to say "No" in a much more constructive way.]]></description>
      <content:encoded><![CDATA[<p>Jim Holmes gave a very nice presentation on leadership at the last <a href="http://www.colarc.org/">Columbus Architecture Group</a> meeting. He has covered much of the same material in <a title="Leadership 101" href="http://frazzleddad.blogspot.com/2009/01/leadership-101-my-take-on-fundamentals.html">a series of posts which you can read on his blog</a>. Maybe it&#8217;s just the way that I think, but as I listened to him speak, I thought about the question of what I do most poorly in the area of leadership. Or, to put a more positive spin on it, the thing which I could change that would most improve my leadership skills.</p>
<p>I think I know what the answer is. Very often, someone will suggest an approach to a problem which strikes me as technically wrong or otherwise misguided. Like a lot of geeks, I have an almost compulsive desire to do things correctly, especially in areas where (to me, anyway) there is a clear-cut difference between "the right way" and "the wrong way" of doing it. Over and over again, I have said "no" in a way which ranged somewhere between insufficiently respectful and inappropriate.</p>
<p>I think I can explain why I do this (and I&#8217;ll do so below, for anyone who actually cares), but the important part is this: <strong>I need to teach myself to say "No" in a much more constructive way</strong>.</p>
<p>When I hear (what I feel is) a bad idea, I think I have this little moment of panic about the bad idea getting into our code, and having to maintain it for 10 years, because goodness knows I have a lot of bad ideas to maintain in our VCS. It&#8217;s like I&#8217;m worried that simply mentioning the idea will doom it (or us) to implementation, so I went to put the barrier in front of it before it can go any further.</p>
<p>This may accomplish the technical goal, but saying "No" in an unconstructive way is poor leadership. I don&#8217;t want to create a climate where people hesitate to suggest solutions to a problem, because they might be incorrect. Indeed, I learned as least as much, if not more, from my mistakes is from my successes, so discussing a bad idea may contribute as much to a project is discussing a good idea. Rather than just saying, "That won&#8217;t work because&#8230;" I need to help the person who suggested the idea explore its implications and work out the ups and downs on their own.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38447&amp;akst_action=share-this" onclick="akst_share('38447', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F22%2F38447%2F', 'The+Leadership+Mistake+I+Keep+Making'); return false;" title="Post to del.icio.us, etc." id="akst_link_38447" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=The%20Leadership%20Mistake%20I%20Keep%20Making&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F22%2F38447%2F" id="akst_email_38447" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>This Blog Is Now (Officially) Free</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/22/38443/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/22/38443/#comments</comments>
    <pubDate>Tue, 22 Sep 2009 18:55:07 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[This Weblog]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38443</guid>
    <description><![CDATA[I&#8217;ve been posting technical articles and source code on this blog for many years now, but I&#8217;ve never formerly specified a license for the material I&#8217;ve posted. Obviously, I wouldn&#8217;t post it if I didn&#8217;t want people to use what I&#8217;ve written, but I understand that my good intentions are not enough to provide the [...]]]></description>
      <content:encoded><![CDATA[<p>I&#8217;ve been posting technical articles and source code on this blog for many years now, but I&#8217;ve never formerly specified a license for the material I&#8217;ve posted. Obviously, I wouldn&#8217;t post it if I didn&#8217;t want people to use what I&#8217;ve written, but I understand that my good intentions are not enough to provide the legal confidence some projects will require to include the code I&#8217;ve demonstrated in their work.</p>
<p>Therefore, I&#8217;ve updated the <a href="http://blogs.teamb.com/craigstuntz/about/">About</a> page to include formal licensing terms. In particular, any source code I&#8217;ve written and posted here is available under the <a href="http://opensource.org/licenses/mit-license.php">MIT license</a>, which should allow you to do almost anything you want to with it, but read the <a href="http://blogs.teamb.com/craigstuntz/about/">About</a> page for the particulars.</p>
<p>Thanks to <a href="http://techencoder.com/">Robert Claypool</a> for pointing this out.</p>
<p>One other bit of news about this site: Readers who prefer to be informed of new posts via Twitter can now <a href="http://twitter.com/craigstuntz">follow the blog there</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38443&amp;akst_action=share-this" onclick="akst_share('38443', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F22%2F38443%2F', 'This+Blog+Is+Now+%28Officially%29+Free'); return false;" title="Post to del.icio.us, etc." id="akst_link_38443" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=This%20Blog%20Is%20Now%20%28Officially%29%20Free&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F22%2F38443%2F" id="akst_email_38443" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Static Analysis and Generated Code</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/16/38396/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/16/38396/#comments</comments>
    <pubDate>Wed, 16 Sep 2009 19:18:53 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[Delphi]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38396</guid>
    <description><![CDATA[In recent months, I&#8217;ve been thinking about the problem of static analysis in generated code. Static analysis means using tools like FxCop and NDepend (for .NET apps) lint (for C) and CodeHealer (for Delphi) to find potential problems in your source code.  Generated code is code written not by a human being, but by [...]]]></description>
      <content:encoded><![CDATA[<p>In recent months, I&#8217;ve been thinking about the problem of static analysis in generated code. Static analysis means using tools like FxCop and <a href="http://www.ndepend.com/">NDepend</a> (for .NET apps) <a href="http://en.wikipedia.org/wiki/Lint_%28software%29">lint</a> (for C) and <a href="http://www.socksoftware.com/codehealer.php">CodeHealer</a> (for Delphi) to find potential problems in your source code.  Generated code is code written not by a human being, but by a tool, such as generated classes for a Entity Framework or LINQ to SQL model, an import for a COM type, or code created by a form generator. Static analysis is intended to find code which is either incorrect or difficult to maintain. The issue exists in any environment where generated code and static analysis meet, but it&#8217;s mainly a problem for me personally in C# and Delphi applications.</p>
<h3>A Useful, But Imperfect, Tool</h3>
<p>Static analysis can be incredibly useful. It finds errors in much the same way that compilers report hints and warnings, but at a significantly deeper level. Compilers typically report a hint or a warning only in cases where the compiler is completely certain that there is a problem with the code, like a completely unused variable. Static analysis tools, on the other hand, can report errors in cases where, for example, the code itself might function, but appears to be too complex to be maintainable. Obviously, there is a gray area between maintainable and unmaintainable, and every static analysis tool I have ever tried has returned false positives. FxCop, for example, will complain that an internal type is never instantiated if the only time it is ever instantiated is inside of a LINQ to Entities query; it doesn&#8217;t seem to be able to "see into the Expression."</p>
<h3>For Code Written By Humans Only</h3>
<p>Static analysis is close to useless for generated code, because it is generated by a tool, tends to always function correctly, and is presumably never maintained by humans, at least directly. But generated code tends to really set off alarms on static analysis tools, due to high line counts, cyclomatic complexities, and numbers of parameters, no unit tests, unusual type and member names, etc. In other words, in generated code <em>functionality </em>is much more important than <em>maintainability</em>. But in non-generated code, maintainability is at least as important as functionality. The best solution is to convince your static analysis tool to ignore the generated code altogether, but this is often easier said than done.</p>
<p>When I run FxCop or NDepend against the source code for our commercial applications, for example, they report a large number of errors, with the majority coming from generated code. The reality is that no tool I have used can consistently distinguish between unmaintainable code written by code generators and unmaintainable code written by programmers, automatically. Therefore, in order to get the maximum benefit from static analysis, we have some additional work to do in order to help the tools look at only the code where their analysis will return useful information for developers.</p>
<h3>Excluding Generated Code From Static Analysis</h3>
<p>The .NET framework includes an attribute, <a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.generatedcodeattribute.aspx">GeneratedCode</a>, which is intended to tell tools such as FxCop to ignore parts of your code. Also, FxCop has its own attribute, <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.codeanalysis.suppressmessageattribute.aspx">SuppressMessage</a> which instructs the tool not to report individual messages in specific cases, and individual tests can be turned off. CodeHealer can be told to suppress a certain number of messages, and you can turn individual tests on and off.</p>
<p>Even with these tools, however, the line between generated and non-generated code is not always clear. FxCop, for example, looks only at compiled assemblies, not at source code. If you have a partial class containing both generated code and human-written code, it&#8217;s important to recall that FxCop cannot tell the difference between the parts of the class which came from the generated code file and the parts which came from the non-generated file. The distinction simply does not exist in the compiled assembly, because "partial" classes are combined at compile time by the C# compiler. So you&#8217;re left with the choice of putting the GeneratedCode attribute on the entire class, causing static analysis to miss code you wrote, or not putting it on the entire class, resulting in static analysis errors from the generated code. The best solution is probably to keep any code you write as part of a partial class as simple as possible, such as calls into another class which does the real work. Considering that partial classes are typically used for things like forms, or LINQ to SQL types, this is a good practice anyway.</p>
<p>Code generation can also work by producing IL or assembly directly, without a source file at all. Obviously, tools which look only at source code, like CodeHealer or Microsoft StyleCop will miss this sort of code (which is a good thing) by their very design. But tools which reflect into compiled code will see this sort of code as no different from any other code in the assembly unless they are specifically designed to exclude it.</p>
<p>For example, when you have an anonymous type with a large number of members in C#, the compiler will generate (in IL) a constructor with an equivalent number of arguments. NDepend flags these as excessive numbers of arguments, and, indeed, it would be correct if this were a real method which I had written.</p>
<h3>Improving Heuristics to Avoid False Positives</h3>
<p>NDepend offers an additional means of filtering data. The tool has a domain specific language for querying your source code, called CQL, and you can use this to filter the specific areas analyzed by NDepend. I can modify the NDepend rules by editing the CQL, so I can, for example, exclude the cases I&#8217;ve just described (generated constructors with large numbers of parameters) by changing the default rule for "too many arguments," which looks like this:</p>
<blockquote>
<pre><span style="color: #008000">// &lt;Name&gt;</span><strong>Methods with too many parameters (NbParameters)</strong><span style="color: #008000">&lt;/Name&gt;
</span><span style="color: #0000ff">WARN</span> <span style="color: #0000ff">IF</span> <span style="color: #000064">Count</span> <span style="color: #000000">&gt;</span> <strong>0</strong> <span style="color: #0000ff">IN</span> <span style="color: #0000ff">SELECT</span> <span style="color: #0000ff">TOP</span> <strong>10</strong> <span style="color: #0000ff">METHODS</span> <span style="color: #0000ff">WHERE</span> <span style="color: #000064">NbParameters</span> <span style="color: #000000">&gt;</span> <strong>5</strong> <span style="color: #0000ff">ORDER</span> <span style="color: #0000ff">BY</span> <span style="color: #000064">NbParameters</span> <span style="color: #0000ff">DESC</span><span style="color: #000000">
</span><span style="color: #008000">// METHODS WHERE NbParameters &gt; 5 might be painful to call and might degrade performance.
</span><span style="color: #008000">// You should prefer using additional properties/fields to the declaring type to handle
</span><span style="color: #008000">// numerous states. Another alternative is to provide a class or structure dedicated to
</span><span style="color: #008000">// handle arguments passing (for example see the class System.Diagnostics.ProcessStartInfo
</span><span style="color: #008000">// and the method System.Diagnostics.Process.Start(ProcessStartInfo))
</span><span style="color: #008000">// See the definition of the NbParameters metric here </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbParameters">http://www.ndepend.com/Metrics.aspx#NbParameters</a></span></pre>
</blockquote>
<p>to this:</p>
<blockquote>
<pre><span style="color: #0000ff">WARN</span> <span style="color: #0000ff">IF</span> <span style="color: #000064">Count</span> <span style="color: #000000">&gt;</span> <strong>0</strong> <span style="color: #0000ff">IN</span> <span style="color: #0000ff">SELECT</span> <span style="color: #0000ff">TOP</span> <strong>10</strong> <span style="color: #0000ff">METHODS</span> <span style="color: #0000ff">
    WHERE</span> <span style="color: #000064">NbParameters</span> <span style="color: #000000">&gt;</span> <strong>5</strong> <span style="color: #0000ff">
        <span style="color: #ff0000">AND</span></span><span style="color: #ff0000"> </span><span style="color: #ff0000">!</span><span style="color: #ff0000">IsGeneratedByCompiler</span><span style="color: #0000ff">
    ORDER</span> <span style="color: #0000ff">BY</span> <span style="color: #000064">NbParameters</span> <span style="color: #0000ff">DESC</span></pre>
</blockquote>
<p>&#8230;and the false positives go away. Unfortunately, this only fixes one test. Similar CQL appears in other default NDepend metrics, like this one:</p>
<blockquote>
<pre><span style="color: #008000">// &lt;Name&gt;</span><strong>Quick summary of methods to refactor</strong><span style="color: #008000">&lt;/Name&gt;</span><span style="color: #000000">
</span><span style="color: #0000ff">WARN</span> <span style="color: #0000ff">IF</span> <span style="color: #000064">Count</span> <span style="color: #000000">&gt;</span> <strong>0</strong> <span style="color: #0000ff">IN</span> <span style="color: #0000ff">SELECT</span> <span style="color: #0000ff">TOP</span> <strong>10</strong> <span style="color: #0000ff">METHODS</span> <span style="color: #008000">/*OUT OF "YourGeneratedCode" */</span> <span style="color: #0000ff">WHERE</span><span style="color: #000000"> 

                                           </span><span style="color: #008000">// Metrics' definitions
</span><span style="color: #000000">     </span><span style="color: #000000">(</span><span style="color: #000000">  </span><span style="color: #000064">NbLinesOfCode</span> <span style="color: #000000">&gt;</span> <strong>30</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">              </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCode">http://www.ndepend.com/Metrics.aspx#NbLinesOfCode</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">NbILInstructions</span> <span style="color: #000000">&gt;</span> <strong>200</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">          </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbILInstructions">http://www.ndepend.com/Metrics.aspx#NbILInstructions</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">CyclomaticComplexity</span> <span style="color: #000000">&gt;</span> <strong>20</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">       </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#CC">http://www.ndepend.com/Metrics.aspx#CC</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">ILCyclomaticComplexity</span> <span style="color: #000000">&gt;</span> <strong>50</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">     </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#ILCC">http://www.ndepend.com/Metrics.aspx#ILCC</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">ILNestingDepth</span> <span style="color: #000000">&gt;</span> <strong>4</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">              </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#ILNestingDepth">http://www.ndepend.com/Metrics.aspx#ILNestingDepth</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #ff0000"><strong>NbParameters &gt; </strong><strong>5</strong></span> <span style="color: #0000ff">OR</span><span style="color: #000000">                </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbParameters">http://www.ndepend.com/Metrics.aspx#NbParameters</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">NbVariables</span> <span style="color: #000000">&gt;</span> <strong>8</strong> <span style="color: #0000ff">OR</span><span style="color: #000000">                 </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbVariables">http://www.ndepend.com/Metrics.aspx#NbVariables</a></span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #000064">NbOverloads</span> <span style="color: #000000">&gt;</span> <strong>6</strong> <span style="color: #000000">)</span><span style="color: #000000">                  </span><span style="color: #008000">// </span><span style="color: #008000"><a href="http://www.ndepend.com/Metrics.aspx#NbOverloads">http://www.ndepend.com/Metrics.aspx#NbOverloads</a></span><span style="color: #008000">
</span><span style="color: #000000">     </span><span style="color: #0000ff">AND</span><span style="color: #000000"> 

     </span><span style="color: #008000">// Here are some ways to avoid taking account of generated methods.
</span><span style="color: #000000">     </span><span style="color: #000000">!</span><span style="color: #000000">(</span> <span style="color: #000064">NameIs</span> <span style="color: #a31515">"InitializeComponent()"</span> <span style="color: #0000ff">OR</span><span style="color: #000000">
        </span><span style="color: #008000">// NDepend.CQL.GeneratedAttribute is defined in the redistributable assembly $NDependInstallDir$\Lib\NDepend.CQL.dll
</span><span style="color: #000000">        </span><span style="color: #008000">// You can define your own attribute to mark "Generated".
</span><span style="color: #000000">        </span><span style="color: #000064">HasAttribute</span> <span style="color: #a31515">"OPTIONAL:NDepend.CQL.GeneratedAttribute"</span><span style="color: #000000">)</span></pre>
</blockquote>
<p>These must all be fixed individually. On the other hand, at least they <em>can </em>be fixed by easily changing the heuristics of the rule, instead of by excluding specific cases, as with many other static analysis tools.</p>
<h3>One Time Pain</h3>
<p>The real win from static analysis tools comes from integrating them into an automated build process. Tools like FinalBuilder and MSBuild can easily be configured to run all of the tools mentioned so far. This allows you to fail the build if potentially unmaintainable code is checked in. The first time you use any static analysis tool, you will probably need to spend a substantial effort in order to get the project to the point where it will not fail the build with existing code. This may involve turning off individual rules (you can gradually turn them on later), fixing specific violations, and excluding code such as generated code. You will then need to integrate the tool into your automated build process. This is, in all honesty, a fair bit of work, but it&#8217;s really a one-time pain. After that, the analysis will pay you back for your effort, day in and day out.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38396&amp;akst_action=share-this" onclick="akst_share('38396', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F16%2F38396%2F', 'Static+Analysis+and+Generated+Code'); return false;" title="Post to del.icio.us, etc." id="akst_link_38396" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Static%20Analysis%20and%20Generated%20Code&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F16%2F38396%2F" id="akst_email_38396" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>How to Think Like the Entity Framework Presentation Available for Free Download</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/11/38394/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/11/38394/#comments</comments>
    <pubDate>Fri, 11 Sep 2009 11:19:11 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[CodeRage]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38394</guid>
    <description><![CDATA[My CodeRage presentation, "How to Think Like the Entity Framework (and why you might want to bother learning that in the first place)," is now available for free download.
]]></description>
      <content:encoded><![CDATA[<p>My <a href="http://conferences.embarcadero.com/coderage">CodeRage</a> presentation, "How to Think Like the Entity Framework (and why you might want to bother learning that in the first place)," is now <a href="http://cc.embarcadero.com/Item/27284">available for free download</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38394&amp;akst_action=share-this" onclick="akst_share('38394', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F11%2F38394%2F', 'How+to+Think+Like+the+Entity+Framework+Presentation+Available+for+Free+Download'); return false;" title="Post to del.icio.us, etc." id="akst_link_38394" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=How%20to%20Think%20Like%20the%20Entity%20Framework%20Presentation%20Available%20for%20Free%20Download&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F11%2F38394%2F" id="akst_email_38394" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>How to Customize ASP.NET MVC Authentication</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/09/38390/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/09/38390/#comments</comments>
    <pubDate>Wed, 09 Sep 2009 15:36:02 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38390</guid>
    <description><![CDATA[If you are developing a web application which requires authentication or security features not included in the regular ASP.NET membership feature, you might decide to implement these features yourself. But it seems as if the first instinct of many ASP.NET MVC developers is to do this by customizing their Controllers, because they&#8217;ve decided that AuthorizeAttribute [...]]]></description>
      <content:encoded><![CDATA[<p>If you are developing a web application which requires authentication or security features not included in the regular ASP.NET membership feature, you might decide to implement these features yourself. But it seems as if the first instinct of many ASP.NET MVC developers is to do this by customizing their Controllers, because they&#8217;ve decided that <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx">AuthorizeAttribute</a> can&#8217;t possibly serve their needs. They will decide that the way to do this is to write some sort of parent Controller type which examines the currently logged-in user when an action executes and changes the result of the action based on who they are. Others will try to re-implement AuthorizeAttribute without ever examining the source code for the original.</p>
<p>These are very bad approaches, for two important reasons:</p>
<ol>
<li><strong>They don&#8217;t work.</strong> If your action result is cached by ASP.NET, then <em>the action will not even run </em>the next time it is requested. AuthorizeAttribute handles this correctly. Code you write in a Controller <em>cannot </em>handle this. Code you write in a custom action filter <em>could</em> work, if you cut and paste the implementation from AuthorizeAttribute. But AuthorizeAttribute is unsealed, so why cut and paste, when you can subtype?</li>
<li>The modularity is wrong. You should aim to develop MVC sites which can be used with any authentication (or role) provider, whether it is ASP.NET membership, domain authentication, OpenId, or a custom membership provider. Wiring authentication concerns into a Controller makes this extremely difficult.</li>
</ol>
<p>I&#8217;ve already hinted at the correct solution for the problem: If you cannot find an out of the box membership provider which does what you need, then <a title="Windows Identity Foundation" href="http://www.microsoft.com/forefront/geneva/en/us/">look harder</a>. If you still can&#8217;t find one, <a title="Implementing a Membership Provider" href="http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx">write your own</a>. Here is a <a href="http://www.asp.net/learn/videos/video-189.aspx">video</a> and an <a href="http://www.devx.com/asp/Article/29256">article</a> on how to do it. Similarly, <a title="Implementing a Role Provider" href="http://msdn.microsoft.com/en-us/library/8fw7xh74.aspx">the role provider can also be customized</a>. In other words, the correct extensibility point for membership in an MVC site is exactly the same as the extensibility point for membership in a non-MVC ASP.NET site.</p>
<p>AuthorizeAttribute does a very simple thing in a somewhat complicated way. The simple thing it does is to tie the MVC framework into the existing ASP.NET membership system, which is quite customizable. That&#8217;s why I am skeptical about claims that AuthorizeAttribute can never serve someone&#8217;s needs. The implementation is more complex than one might imagine is required on first consideration because it must both be thread safe and cooperate with caching, which makes attempting to re-invent it at a different level a doubly bad idea.</p>
<p>Although AuthorizeAttribute doesn&#8217;t do very much, you may decide that it&#8217;s specific behavior is not correct for your project. In that case, it is generally a better idea to subtype AuthorizeAttribute instead of re-inventing your own. This allows you to preserve desirable behavior (like cooperating with caching) while customizing the behavior you need. You will need to override the AuthorizeCore method, taking careful note of the comments (in the <a href="http://aspnet.codeplex.com/Wiki/View.aspx?title=MVC">MVC source code</a> for the inherited method) on thread-safety.</p>
<p>One final word about customizing security: Your general approach should be to use proven, off the shelf, actively maintained solutions and customize as little as possible. If the problem you are trying to solve is not strictly security-related (like adding a custom field to a user profile), then do not alter (and potentially compromise) your security in order to solve it. Instead, find a more appropriate solution, like storing the information elsewhere, such as in <a href="http://www.microsoft.com/forefront/geneva/en/us/">an ASP.NET profile</a> or your own DB. Similarly, don&#8217;t use something which is not intended to have hard security, like Session, for security purposes. <a href="http://www.drdobbs.com/windows/184405837">Attackers can and do hijack session information</a>. <strong>Doing security correctly is hard, and the consequences of small mistakes can be high.</strong> <a href="http://www.cl.cam.ac.uk/~rja14/Papers/satan.pdf">Even experts in the field make mistakes which can take years to uncover</a>. Even if you follow to the letter everything which is known about implementing good security, today, your implementation may be obsolete tomorrow.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38390&amp;akst_action=share-this" onclick="akst_share('38390', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F09%2F38390%2F', 'How+to+Customize+ASP.NET+MVC+Authentication'); return false;" title="Post to del.icio.us, etc." id="akst_link_38390" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=How%20to%20Customize%20ASP.NET%20MVC%20Authentication&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F09%2F38390%2F" id="akst_email_38390" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>How to Think Like the ADO.NET Entity Framework at CodeRage 4</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/09/04/38373/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/09/04/38373/#comments</comments>
    <pubDate>Fri, 04 Sep 2009 21:45:18 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[CodeRage]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38373</guid>
    <description><![CDATA[This coming Wednesday 9 September I&#8217;ll be doing a presentation at the free, online CodeRage 4 conference:
How to Think Like the ADO.NET Entity Framework
(and why you might want to bother learning to do so in the first place)
In order to use the ADO.NET Entity Framework effectively, you must understand its value-based data model, which is [...]]]></description>
      <content:encoded><![CDATA[<p>This coming Wednesday 9 September I&#8217;ll be doing a presentation at the <a href="http://conferences.embarcadero.com/coderage">free, online CodeRage 4</a> conference:</p>
<h3>How to Think Like the ADO.NET Entity Framework</h3>
<p><img style="float: right" src="/files/2009/09/coderagelogo_1956.jpg" alt="" width="196" height="196" />(and why you might want to bother learning to do so in the first place)</p>
<blockquote><p>In order to use the ADO.NET Entity Framework effectively, you must understand its value-based data model, which is distinctly different from the SQL and ORM approaches to representing and querying data. Programmers who approach the Entity Framework as "just another ORM" often find themselves frustrated or disappointed, a common reaction to trying to force a square peg into a round hole. This presentation examines the Entity Data Model in-depth, explaining where it fits into the context of a larger application, and demonstrates different techniques for retrieving and altering data. Also covered are performance considerations and future directions.</p></blockquote>
<p>Sound like something you&#8217;d like to learn about? The conference is free, but <a href="https://www124.livemeeting.com/lrs/advancedsw_ccc/Registration.aspx?pageName=1694szd61kc6s3vx">you must register to attend</a>. I&#8217;ll be on at <a href="http://www.timeanddate.com/worldclock/converter.html?year=2009&amp;month=9&amp;day=9&amp;hour=17&amp;min=0&amp;sec=0&amp;p1=283&amp;p2=805">5:00 PDT; you can convert that to your local time</a>.</p>
<p>Embarcadero has me in the <a href="http://www.embarcadero.com/products/delphi-prism">Delphi Prism</a> track, but my examples will be in C#.</p>
<p>If .NET&#8217;s not your cup of tea, there are <a href="http://conferences.embarcadero.com/coderage/sessions">plenty of other sessions</a> you can join.</p>
<p><strong>Update:</strong> The conference is over, but you can <a href="http://cc.embarcadero.com/Item/27284">download a recording of my session</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38373&amp;akst_action=share-this" onclick="akst_share('38373', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F04%2F38373%2F', 'How+to+Think+Like+the+ADO.NET+Entity+Framework+at+CodeRage+4'); return false;" title="Post to del.icio.us, etc." id="akst_link_38373" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=How%20to%20Think%20Like%20the%20ADO.NET%20Entity%20Framework%20at%20CodeRage%204&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F09%2F04%2F38373%2F" id="akst_email_38373" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>On That Delphi 7 Virus and Ken Thompson&#8217;s Turing Award Speech</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/08/20/38361/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/08/20/38361/#comments</comments>
    <pubDate>Thu, 20 Aug 2009 15:38:16 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[ACM]]></category>

		<category><![CDATA[Delphi]]></category>

		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38361</guid>
    <description><![CDATA[In 1984, Ken Thompson, the operating system and programming language pioneer, received the ACM&#8217;s Turing Award. In his short, highly-readable Turing Award speech, he describes "the cutest program I ever wrote." He notes that because the C compiler is written in C, it is possible to alter the source code maliciously to produce a malicious [...]]]></description>
      <content:encoded><![CDATA[<p>In 1984, Ken Thompson, the operating system and programming language pioneer, received the ACM&#8217;s Turing Award. In <a title="Reflections On Trusting Trust" href="http://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf">his short, highly-readable Turing Award speech</a>, he describes "the cutest program I ever wrote." He notes that because the C compiler is written in C, it is possible to alter the source code maliciously to produce a malicious compiler executable. The malicious code can then be removed from the C source, and the original code recompiled. The malicious code remains in the "new" executable, however, because it was prouced by the trojaned compiler.</p>
<p>If you can persuade someone to use your modified compiler, or if you can modify the compiler on their machine, then you can infect the executables they produce, even if they recompile the compiler itself from source code! If that seems unlikely or difficult, read the whole paper. It&#8217;s easier than you think. Thompson concludes:</p>
<blockquote><p>The moral is obvious. You can&#8217;t trust code that you did not totally create yourself. (Especially code from companies that employ people like me.) No amount of source-level verification or scrutiny will protect you from using untested code. In demonstrating the possibility of this kind of attack, I picked on the C compiler. I could have picked on any program-handling program such as an assembler, a loader, or even hardware microcode. As the level of program gets lower, these bugs will be harder and harder to detect. A well-installed microcode bug will be almost impossible to detect.</p></blockquote>
<p>Now it seems that <a title="Delphi developer virus exposes weakness in anti-virus defences" href="http://www.itwriting.com/blog/1717-delphi-developer-virus-exposes-weakness-in-anti-virus-defences.html">somebody has actually gone and done this with old versions of Delphi</a>. Frankly, I&#8217;m surprised it took so long. Perhaps this is just the first time we&#8217;ve noticed. But the problem described by Thompson is so insidious that in the quarter century since he gave his address (which really just gave additional prominence to an issue discovered decades before that) it&#8217;s almost remarkable that this technique is not more widespread. It&#8217;s also interesting that this specific case is relatively innocuous; the virus does nothing more than reproduce itself, and only affects a very old compiler. Is this a test shot? Someone whose curiosity got the better of them?</p>
<p>I don&#8217;t know. But the historical perspective is clear: This is not about Delphi, and it&#8217;s not about the malware of the week. It&#8217;s an old question of trust becoming new again.</p>
<p><a title="Countering Trusting Trust through Diverse Double-Compiling" href="http://www.acsa-admin.org/2005/abstracts/47.html">Here is one proposal for countering these attacks</a>. Interestingly, the technique can sometimes find unintended compiler bugs, as well. They can be hard to distinguish sometimes!</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38361&amp;akst_action=share-this" onclick="akst_share('38361', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F20%2F38361%2F', 'On+That+Delphi+7+Virus+and+Ken+Thompson%26%238217%3Bs+Turing+Award+Speech'); return false;" title="Post to del.icio.us, etc." id="akst_link_38361" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=On%20That%20Delphi%207%20Virus%20and%20Ken%20Thompson%26%238217%3Bs%20Turing%20Award%20Speech&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F20%2F38361%2F" id="akst_email_38361" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>InterBase 2009 Hotfix Update 3</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/08/19/38359/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/08/19/38359/#comments</comments>
    <pubDate>Wed, 19 Aug 2009 13:38:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38359</guid>
    <description><![CDATA[InterBase 2009 Hotfix Update 3 (version 9.0.3.437) is out. See the readme for the full list of bug fixes.
]]></description>
      <content:encoded><![CDATA[<p>InterBase 2009 Hotfix Update 3 (version 9.0.3.437) is out. See <a title="InterBase 2009 Hotfix Update 3 Readme" href="http://edn.embarcadero.com/article/39821">the readme</a> for the full list of bug fixes.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38359&amp;akst_action=share-this" onclick="akst_share('38359', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F19%2F38359%2F', 'InterBase+2009+Hotfix+Update+3'); return false;" title="Post to del.icio.us, etc." id="akst_link_38359" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=InterBase%202009%20Hotfix%20Update%203&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F19%2F38359%2F" id="akst_email_38359" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Embarcadero Change Manager To Support InterBase, Firebird</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/08/13/38352/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/08/13/38352/#comments</comments>
    <pubDate>Thu, 13 Aug 2009 18:15:11 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38352</guid>
    <description><![CDATA[Embarcadero&#8217;s Change Manager will support InterBase (and Firebird) this fall, according to PM Gordan Lucas. He even has video evidence!
Change Manager 5.1.1 will add support for InterBase 2007 and 2009 databases to: compare, version, and synchronize schemas; compare, synchronize, move, and mask data; and compare, version, and monitor version configurations for compliance and tracking.
And for [...]]]></description>
      <content:encoded><![CDATA[<p>Embarcadero&#8217;s <a href="http://www.embarcadero.com/embarcadero-change-manager">Change Manager</a> will support InterBase (and Firebird) this fall, <a href="http://gordon-lucas.blogspot.com/2009/08/change-manager-and-interbase.html">according to PM Gordan Lucas</a>. He even has video evidence!</p>
<blockquote><p>Change Manager 5.1.1 will add support for InterBase 2007 and 2009 databases to: compare, version, and synchronize schemas; compare, synchronize, move, and mask data; and compare, version, and monitor version configurations for compliance and tracking.</p>
<p>And for any Firebird SQL users out there, you can join the party too because Change Manager will support versions 1.5 and 2.0 of that database. Move your data to and from any platform we support and move and compare schemas between Firebird and InterBase.</p></blockquote>
<p>Also, it&#8217;s worth noting <a href="http://etnaweb04.embarcadero.com/bogo-info/">you can get Change Manager for free with the purchase of another Embarcadero tool</a>, including Delphi or InterBase.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38352&amp;akst_action=share-this" onclick="akst_share('38352', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F13%2F38352%2F', 'Embarcadero+Change+Manager+To+Support+InterBase%2C+Firebird'); return false;" title="Post to del.icio.us, etc." id="akst_link_38352" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Embarcadero%20Change%20Manager%20To%20Support%20InterBase%2C%20Firebird&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F13%2F38352%2F" id="akst_email_38352" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>2D Goggles - Babbage and Lovelace</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/08/13/38348/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/08/13/38348/#comments</comments>
    <pubDate>Thu, 13 Aug 2009 15:32:05 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38348</guid>
    <description><![CDATA[Warning: The following comic has been demonstrated to severely lower developer productivity upon first introduction.
Sydney Padua has done the impossible: Created a programming comic which I like as much as XKCD. You can start at the beginning or read the latest, thrilling episode. She also did a special for the BBC. Navigation is a bit [...]]]></description>
      <content:encoded><![CDATA[<blockquote><p>Warning: The following comic has been demonstrated to severely lower developer productivity upon first introduction.</p></blockquote>
<p>Sydney Padua has done the impossible: Created a programming comic which I like as much as <a href="http://xkcd.com">XKCD</a>. You can <a title="Ada Lovelace - The Origin!" href="http://sydneypadua.com/2dgoggles/lovelace-the-origin-2/">start at the beginning</a> or read <a title="Lovelace and Babbage vs. the Client" href="http://sydneypadua.com/2dgoggles/lovelace-and-babbage-vs-the-client-pt-2/">the latest, thrilling episode</a>. She also did <a title="Techlab" href="http://news.bbc.co.uk/2/hi/technology/8139075.stm">a special for the BBC</a>. Navigation is a bit awkward (look for the "next" and "back" links above each post), but entirely worth the effort.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38348&amp;akst_action=share-this" onclick="akst_share('38348', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F13%2F38348%2F', '2D+Goggles+-+Babbage+and+Lovelace'); return false;" title="Post to del.icio.us, etc." id="akst_link_38348" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=2D%20Goggles%20-%20Babbage%20and%20Lovelace&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F08%2F13%2F38348%2F" id="akst_email_38348" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Columbus Give Camp</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/07/21/38329/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/07/21/38329/#comments</comments>
    <pubDate>Tue, 21 Jul 2009 14:32:50 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[General Software Development]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38329</guid>
    <description><![CDATA[This past weekend I, along with around 50 other local geeks, volunteered three days of my time to build web applications for eight different Columbus-area nonprofits. Columbus Give Camp is based on a similar series of events in Michigan. The Columbus Give Camp was hosted by Quick Solutions, who, conveniently, are located five floors above [...]]]></description>
      <content:encoded><![CDATA[<p>This past weekend I, along with around 50 other local geeks, volunteered three days of my time to build web applications for eight different Columbus-area nonprofits. <a href="http://www.columbusgivecamp.org/">Columbus Give Camp</a> is based on <a href="http://michigangivecamp.org/">a similar series of events in Michigan</a>. The Columbus Give Camp was hosted by <a href="http://www.quicksolutions.com/">Quick Solutions</a>, who, conveniently, are located five floors above my own office. The event was a huge success. I&#8217;m particularly proud of the work my team did, taking the project from nothing to live and in production in just a few days work.</p>
<p>The Give Camp organizers found charities who needed web development donations and split the registered developers into teams based upon skill sets and organization needs. I was assigned to the team for the <a href="http://www.ficccs.com/">Shiloh Family Institute College Choir Concert Series</a>, a small organization which sponsors a series of gospel choir performances once a year. They needed a web site to promote the organization, list upcoming events, allow their patrons to register for e-mail alerts of scheduled concerts, and think their donors. Critically, the site had to be easy to maintain for administrators without computer expertise. My team included Brahma Ghosh, <a href="http://geekswithblogs.net/bjackett/">Brian Jackett</a>, Joel Broughton, <a href="http://josephours.blogspot.com/">Joseph Ours</a>, and Peter Vasys. Prior to the start of Give Camp, Brahma, the project manager, met with representatives of the organization and produced a mockup of each page we would build in the site.</p>
<p>We decided to build the sites using (non-MVC) ASP.NET, because that was the "least common denominator" of the skill sets of our team members. The requirements for the site specified displaying 10-20 concerts and around 10 sponsors. In view of the tiny data set and the emphasis on ease-of-use for the folks who will be maintaining the site, we decided against using a database or off-the-shelf content management system. Instead, we built the site such that the content areas would simply be editable in a WYSIWYG editor if you are logged into the site. So the site maintainers only needed to be instructed as to how to log in, and the rest is obvious.</p>
<p>Here is a part of what a logged-in user sees on the site homepage; you can compare that with <a href="http://www.ficccs.com/">the production site</a> in order to see the difference.</p>
<div id="attachment_38330" class="wp-caption aligncenter" style="width: 510px"><a href="/files/2009/07/sficccs_1512.png"><img src="/files/2009/07/sficccs_1512.png" alt="WYSIWYG editor on site home page" width="500" height="259" /></a><p class="wp-caption-text">WYSIWYG editor on site home page</p></div>
<p>At the beginning of Friday night, we met our clients, discussed the requirements for the project, settled on which technology we would use to build the site, and got to work. One of the first things we needed to do was to register a domain name and secure hosting so that the site could go live on Sunday. Also, we set up a Subversion repository on <a href="http://www.assembla.com/">assembla.com</a>. Then we split up the work and started writing code. The project manager created a solution for the project and checked it into subversion. I started creating repositories for the data which would be editable on the site. Because each dataset would only hold 10 through 20 records maximum, we decided to use XML files instead of a database to hold the data. Performance is not a problem with such a small dataset, and using files instead of a database allows non-technical users to easily move the site from one hosting provider to another. Also, we used the repository pattern, so it&#8217;s possible to switch out the storage without changing a line of web client code in the event the site ever grows beyond its current scale. The first thing I did was check in the public interfaces for the repositories so that the people creating the web pages could start work before I was done with the implementation. Other team members created web pages, started the site design, and began implementing a Google Maps feature on the "upcoming concert" page.</p>
<p>We wrote unit tests for all of the repositories in the site. In view of the very short amount of time we had to develop the site, that might seem surprising. In fact, however, writing unit tests allowed us to test the repository functionality before the web pages which used the repositories were finished, so even though it was a little extra work, it improved our ability to work concurrently.</p>
<p>I went home to get some sleep around 2 a.m. Friday night, but some people worked through the whole night. The Give Camp organizers supplied us with food, caffeine, and entertainment. I spent most of Saturday implementing a feature to allow the site maintainers to add and remove sponsors, including a feature to upload sponsor logos and thumbnail them to the correct size for the site. By the end of Saturday, just after midnight, all of the major features of the site except for the Google Maps were working, and we were down to fixing bugs and typos. A pleasant surprise for me was that the food provided was consistently good and occasionally even healthy; the Give Camp organizers had recruited some local restaurants as <a href="http://www.columbusgivecamp.org/GiveCamp/Home/Sponsor">sponsors</a>, and a grateful charity brought in some large containers of fruit.</p>
<p>Incidentally, there are some <a href="http://www.flickr.com/photos/tags/columbusgivecamp2009/">photos of Give Camp on Flickr</a>.</p>
<p>We spent the first half of Sunday cleaning up defects, and the second half testing and fixing typos in the content. Some of the other team members implemented the Google Maps feature in two different ways in order to be sure that we would have at least one which worked before we deployed the site to production.</p>
<p>At 4:00 p.m. on Sunday, all eight teams presented their work. There was a real diversity of projects. In our case, we built a simple site from scratch and finished it the same weekend. Other teams added new features to existing sites. One team was given three or four different sites using different technologies with the instructions to make them have a common look and feel. Every one of the clients appeared completely delighted with the end results.</p>
<p>Whenever I read "studies" which claim that the majority of software projects fail, I have to balance these claims against my own personal experience, which demonstrates that projects can be successful even with very little time and team members who have never spoken to each other before the instant the project begins. So why did this project work out so well?</p>
<ul>
<li>Our project manager did excellent work up front with the client, so we knew exactly what we needed to build.</li>
<li>The client had a good sense of priorities for the project.</li>
<li>The team was highly motivated. We were all participating by choice. The Give Camp organizers kept the emphasis on fun. The deadline was challenging, but realistic.</li>
<li>The Give Camp organizers did a great job splitting up the teams. We had people with project management skills, design skills, and development skills.</li>
<li>We used off-the-shelf functionality where appropriate. For example, the mailing list registration is handled via the <a href="http://www.mailchimp.com/">MailChimp</a> API. The map feature is done with <a href="http://code.google.com/apis/maps/">Google Maps</a>. Event photos are hosted on Flickr. We used their API to show a single image when there was only one image of an event available, and a slideshow when multiple images were available.</li>
<li>We built only what was needed. Using an off-the-shelf CMS would have delivered more features, but at the cost of being difficult for the client to maintain, both in terms of the user interface and a database on the back end. The client made it clear that ease-of-use was paramount, and we stuck to that.</li>
<li>There was no dead weight on the team. <a href="http://elegantcode.com/2009/01/14/bad-apple-behaviors/">A single, unmotivated developer can slow down an entire team</a>. Since everyone was there by choice, and everyone was qualified for the work, we didn&#8217;t have to deal with any problem team members.</li>
<li>We had our choice of technologies, so we could choose a platform with which everyone on the team had at least some familiarity.</li>
</ul>
<p>Give Camp was the most fun I&#8217;ve had coding in some time, even though (non-MVC) ASP.NET is not my preferred platform. The emphasis on fun, the opportunity to try things outside of my comfort zone, and the excellent team atmosphere made it a great experience.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38329&amp;akst_action=share-this" onclick="akst_share('38329', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F21%2F38329%2F', 'Columbus+Give+Camp'); return false;" title="Post to del.icio.us, etc." id="akst_link_38329" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Columbus%20Give%20Camp&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F21%2F38329%2F" id="akst_email_38329" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Skip(0) in LINQ and Testing</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/07/07/38326/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/07/07/38326/#comments</comments>
    <pubDate>Tue, 07 Jul 2009 19:53:34 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38326</guid>
    <description><![CDATA[A couple of weeks ago, I wrote In LINQ, Beware of Skip(0). In that post, I observed that calling Skip(0) on a query result in LINQ, which has no effect on the dataset returned, imposes a performance penalty with at least some LINQ providers. At the time I commented that there might be some desirable [...]]]></description>
      <content:encoded><![CDATA[<p>A couple of weeks ago, I wrote <a href="http://blogs.teamb.com/craigstuntz/2009/06/10/38313/">In LINQ, Beware of Skip(0)</a>. In that post, I observed that calling Skip(0) on a query result in LINQ, which has no effect on the dataset returned, imposes a performance penalty with at least some LINQ providers. At the time I commented that there might be some desirable behavior of this that I had missed. Sure enough, one of the developers on the LINQ to SQL team <a href="http://blogs.teamb.com/craigstuntz/2009/06/10/38313/#comment-7652">noted in comments that Skip(0) will cease to be a no-op in LINQ to SQL in .NET 4.0</a>, and supplied a perfectly reasonable explanation for the change.</p>
<p>Given that calling Skip(0) introduces a performance penalty, but there is a reason for introducing that penalty, should we avoid making this call? The short answer is yes, the performance improvement is worth it, but don&#8217;t forget the rule that you should have one test case for every conditional in your code. This rule is generally applied to unit testing, but in this case the appropriate test is an integration test, since you need to be sure that the LINQ provider will perform acceptably and not fail altogether when you fetch the data for the second page, which is now an entirely different query than that used to retrieve the data for the first page.</p>
<p>When I first observed the issue, I was happy to discover that I could make the query which fetches data for the first page of a result set (which happens to be the page which users most commonly request) 10 times faster. Of course, the other way to look at this is that the query that fetches data for the second and all subsequent pages is 10 times slower than the query which fetches data for the first page. Again, given that the first page is displayed much more frequently, that&#8217;s not necessarily a bad thing, <em>as long as it doesn&#8217;t catch you by surprise</em>. Indeed, calling Skip(n), where n &gt; 0, and getting your results not quite as quickly as if you had not called Skip(n) at all is actually the best case; the worst possible case is that the LINQ provider will generate invalid SQL and the query will fail.</p>
<p>Note that it is especially difficult to ensure complete integration testing coverage as you introduce more and more ways that the user can shape a result set. If the user can change the sort order, enter a variety of search queries, etc., it&#8217;s a safe bet that every combination of these options will produce a different query with different performance characteristics. Avoiding calling Skip(0), in other words, does not increase the number of integration test cases for a particular list of data by one; it doubles it.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38326&amp;akst_action=share-this" onclick="akst_share('38326', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F07%2F38326%2F', 'Skip%280%29+in+LINQ+and+Testing'); return false;" title="Post to del.icio.us, etc." id="akst_link_38326" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Skip%280%29%20in%20LINQ%20and%20Testing&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F07%2F38326%2F" id="akst_email_38326" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Kahn Racing Again</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/07/06/38324/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/07/06/38324/#comments</comments>
    <pubDate>Mon, 06 Jul 2009 19:10:32 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Uncategorized]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38324</guid>
    <description><![CDATA[Philippe Kahn is once again competing in the Transpac (sailboat) Ocean race.
]]></description>
      <content:encoded><![CDATA[<p><a href="http://www.pegasus.com/log.htm">Philippe Kahn is once again competing</a> in the Transpac (sailboat) Ocean race.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38324&amp;akst_action=share-this" onclick="akst_share('38324', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F06%2F38324%2F', 'Kahn+Racing+Again'); return false;" title="Post to del.icio.us, etc." id="akst_link_38324" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Kahn%20Racing%20Again&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F07%2F06%2F38324%2F" id="akst_email_38324" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Columbus Give Camp</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/06/16/38321/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/06/16/38321/#comments</comments>
    <pubDate>Tue, 16 Jun 2009 11:55:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Uncategorized]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38321</guid>
    <description><![CDATA[If you&#8217;re a geek in the Central Ohio area, please consider volunteering for Columbus Give Camp, if your schedule permits.
]]></description>
      <content:encoded><![CDATA[<p>If you&#8217;re a geek in the Central Ohio area, please consider volunteering for <a href="http://www.columbusgivecamp.org/GiveCamp/">Columbus Give Camp</a>, if your schedule permits.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38321&amp;akst_action=share-this" onclick="akst_share('38321', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F06%2F16%2F38321%2F', 'Columbus+Give+Camp'); return false;" title="Post to del.icio.us, etc." id="akst_link_38321" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Columbus%20Give%20Camp&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F06%2F16%2F38321%2F" id="akst_email_38321" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>In LINQ, Beware of Skip(0)</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/06/10/38313/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/06/10/38313/#comments</comments>
    <pubDate>Wed, 10 Jun 2009 19:29:44 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38313</guid>
    <description><![CDATA[Calling IQueryable&#60;T&#62;.Skip(0) seems like it should be "free." In other words, since it will have no effect on the resulting data, there should be little to no performance cost for calling it. But this is demonstrably not true in LINQ to Entities, and it occurs to me that LINQ providers are not required to optimize [...]]]></description>
      <content:encoded><![CDATA[<p>Calling <code>IQueryable&lt;T&gt;.Skip(0)</code> <em>seems</em> like it should be "free." In other words, since it will have no effect on the resulting data, there should be little to no performance cost for calling it. But this is demonstrably not true in LINQ to Entities, and it occurs to me that LINQ providers are not required to optimize it away. Therefore, it is probably a good idea to avoid making such a call at all, so that you do not have to concern yourself with whether the provider will generate a slower query if you do it.</p>
<p>Unfortunately, it is not just your own code you need to be concerned with. It turns out that some fairly popular LINQ helpers do this. For example, <a href="http://blog.wekeroad.com/blog/aspnet-mvc-pagedlistt/">Rob Connery&#8217;s PagedList&lt;T&gt;</a> type does it:</p>
<blockquote>
<pre><code><strong>public </strong>PagedList(IQueryable&lt;T&gt; source, <strong>int</strong> index, <strong>int</strong> pageSize)
{
    <strong>this</strong>.TotalCount = source.Count();
    <strong>this</strong>.PageSize = pageSize;
    <strong>this</strong>.PageIndex = index;
    <strong>this</strong>.AddRange(source.Skip((index - 1) * pageSize).Take(pageSize).ToList());</code></pre>
</blockquote>
<p>Index, in this code, is the 1-based page you&#8217;d like to display. When index is 1, the code calls Skip(0), and you get less efficient SQL. Fixing the problem is quite simple:</p>
<blockquote>
<pre><code>    <strong>this</strong>.PageIndex = index;
    var pageData = index &gt; 1 ?
        source.Skip((index - 1) * pageSize).Take(pageSize) : source.Take(pageSize);
    this.AddRange(pageData.ToList());</code></pre>
</blockquote>
<p>Naturally, this only optimizes SQL generation for the first page of results, but since this is by far the most common page a user might display, it can net you a substantial win in server performance.</p>
<p><a href="http://www.squaredroot.com/2008/07/08/PagedList-Strikes-Back/">Troy Goode&#8217;s updated PagedList type</a>, which I have recommended in the past (and still do, with this tweak!), has the same problem. The solution is almost identical, although Troy&#8217;s type is 0-based rather than 1-based. <strong>Update:</strong> <a href="http://pagedlist.codeplex.com/">Troy has now posted an update</a> containing this fix, among many other changes.</p>
<p>The root of the problem in the SQL generation is that when you call Skip(0), LINQ to Entities, in at least some cases, generates SQL like this:</p>
<blockquote><p><code>)  <strong>AS </strong>[Project3]<br />
<strong>WHERE </strong>[Project3].[row_number] &gt; 0<br />
<strong>ORDER BY</strong> [Project3].[TimeRecordDate] <strong>DESC</strong></code></p></blockquote>
<p>The reference to <code>row_number</code> can have a substantial performance impact. In one case I tried with a SQL Server table containing just over 1 million rows, a simple query ran with sub-second performance without this WHERE clause, and over 4 seconds with the WHERE clause, even though the result set was exactly the same.</p>
<p>Now, is this a bug in LINQ to Entities? Or LINQ itself? It&#8217;s hard to say. Both frameworks are doing exactly what you tell them to, even though it doesn&#8217;t make a lot of sense. It seems like a missed opportunity for optimization, but I&#8217;m open to the possibility that there might be some desirable effect of this that I have simply missed. For my own purposes, I am content to simply not call Skip(0) at all.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38313&amp;akst_action=share-this" onclick="akst_share('38313', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F06%2F10%2F38313%2F', 'In+LINQ%2C+Beware+of+Skip%280%29'); return false;" title="Post to del.icio.us, etc." id="akst_link_38313" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=In%20LINQ%2C%20Beware%20of%20Skip%280%29&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F06%2F10%2F38313%2F" id="akst_email_38313" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Early Turbo Pascal History on Hanselminutes</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/05/14/38310/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/05/14/38310/#comments</comments>
    <pubDate>Thu, 14 May 2009 17:27:45 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Delphi]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38310</guid>
    <description><![CDATA[In the most recent episode of Hanselminutes, Scott chats with founders of Mustang Software (creators of Wildcat! BBS) Jim Harrer and Scott Hunter about the BBS era. Wildcat! was written in Turbo Pascal, and Harrer and Hunter state that it was one of the first major applications developed in that language. In the first part [...]]]></description>
      <content:encoded><![CDATA[<p>In the most recent episode of Hanselminutes, <a href="http://www.hanselminutes.com/default.aspx?showID=179">Scott chats with founders of Mustang Software (creators of Wildcat! BBS) Jim Harrer and Scott Hunter about the BBS era</a>. Wildcat! was written in Turbo Pascal, and Harrer and Hunter state that it was one of the first major applications developed in that language. In the first part of the show, they discuss going to California to meet with the Turbo Pascal team, visiting Anders Hejlsberg&#8217;s house, and more early history.</p>
<p>It&#8217;s worth a listen if you&#8217;re interested in the history of the product which started Borland and evolved into Delphi.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38310&amp;akst_action=share-this" onclick="akst_share('38310', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F14%2F38310%2F', 'Early+Turbo+Pascal+History+on+Hanselminutes'); return false;" title="Post to del.icio.us, etc." id="akst_link_38310" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Early%20Turbo%20Pascal%20History%20on%20Hanselminutes&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F14%2F38310%2F" id="akst_email_38310" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using DayPilot with ASP.NET MVC</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/05/12/38297/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/05/12/38297/#comments</comments>
    <pubDate>Tue, 12 May 2009 12:45:31 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38297</guid>
    <description><![CDATA[I&#8217;m going to demonstrate how to use the open-source DayPilot Lite calendar control in an ASP.NET MVC application. I will discuss the capabilities of the control and consider the general problem of how to use controls designed for "plain" ASP.NET in MVC applications. I&#8217;m including a demo solution which you can download and run yourself.
Download [...]]]></description>
      <content:encoded><![CDATA[<p>I&#8217;m going to demonstrate how to use the open-source <a href="http://www.daypilot.org/daypilot-lite.html">DayPilot Lite calendar control</a> in an ASP.NET MVC application. I will discuss the capabilities of the control and consider the general problem of how to use controls designed for "plain" ASP.NET in MVC applications. I&#8217;m including a demo solution which you can download and run yourself.<a href="/files/2009/05/daypilot_1277.zip"></a></p>
<p><strong>Download the demo solution: </strong><a href="/files/2009/05/daypilot_1277.zip">DayPilot ASP.NET MVC demo</a></p>
<p>We needed a calendar control for an ASP.NET MVC application. In particular, we needed a control which would show a number of events and when they occur within a particular day, "Outlook-style." I&#8217;ll include a screenshot of the demo application here, since it&#8217;s the best way to explain the type of control we were looking for:</p>
<div id="attachment_38298" class="wp-caption aligncenter" style="width: 295px"><a href="/files/2009/05/daypilot_1274.png"><img src="/files/2009/05/daypilot_1274-285x300.png" alt="DayPilot example" width="285" height="300" /></a><p class="wp-caption-text">DayPilot example</p></div>
<h3>Possible Alternatives to DayPilot</h3>
<p>In my experience, the type of control which works best with ASP.NET MVC is a control which is completely ignorant of ASP.NET, and all the <a href="http://blog.wekeroad.com/blog/i-spose-ill-just-say-it-you-should-learn-mvc/">lies such as ViewState and postbacks</a> which accompany it. In particular, I&#8217;ve had a good deal of success with controls designed for the jQuery JavaScript framework, which is included, by default, with ASP.NET MVC applications. Unfortunately, I was unable to find a jQuery control which data what we needed. The closest I found was <a href="http://www.bytecyclist.com/projects/jmonthcalendar/">jMonthCalendar</a> which cannot display a single day in the manner illustrated above. I would still prefer a jQuery-based solution if one ever turns up.</p>
<p>I did, however, find a couple of controls designed for "plain" ASP.NET which, from an end-user point of view, it exactly what we needed. One was the DayPilot control illustrated above, the other was <a href="http://www.telerik.com/products/aspnet-ajax/scheduler.aspx">the scheduler component included with Telerik&#8217;s control suite</a>. Telerik&#8217;s control claims some support for MVC, but this is really limited to loading calendar data asynchronously, which was not actually what we wanted to do. Also, Telerik&#8217;s control can only be purchased as part of their suite, which is rather expensive if you only need the calendar/scheduler control. Paying for the entire suite would not be a problem for us if it was filled with controls we needed, designed for the environment (MVC) we use. While Telerik seems serious about supporting MVC, they are in the early stages right now, so it is difficult to justify paying for a large suite in order to get a single control, which I would have to use in a mostly-unsupported way. The Telerik control has many more features than the DayPilot control, and, in my opinion, looks a little nicer.</p>
<p>The DayPilot calendar is available in two different editions. There is an open source edition, which is free, and a non-open-source edition, which <a href="http://www.daypilot.org/compare-versions.html">adds features</a>. The principal difference is that the date version includes editing (via postbacks) and UpdatePanel support, which are not really useful in an ASP.NET MVC application anyway. As with Telerik&#8217;s control, I have to adapt the control for use within ASP.NET MVC. So we selected the open source version, even though the paid version is priced reasonably.</p>
<h3>Adapting DayPilot to ASP.NET MVC</h3>
<p>In order to use the DayPilot control in ASP.NET MVC, I wanted to use markup which would look familiar to ASP.NET MVC developers:</p>
<blockquote>
<pre><code>&lt;%= Html.DayPilot(Model, <strong>new</strong> DayPilotViewOptions
                             {
                                 HourHeight = 30
                             }) %&gt;</code></pre>
</blockquote>
<p>This means that I needed to write an Html helper which will render the control based on the data passed in Model and return the literal HTML markup. In order to make that easier, I created two new types, DayPilotData and DayPilotViewOptions, in order to encapsulate access to the properties of the control. The reason I created two different types was to separate the concerns of data for the events (which will be set up in the controller) and display of the control (which is the concern of the view). The types are trivial, so I&#8217;m not going to show them in this post, but you can examine them in the demo solution. There is an overload to this Html helper which does not include the options argument in case you are happy with the defaults.</p>
<blockquote>
<pre><code><strong>        public static string</strong> DayPilot(
            <strong>this</strong> HtmlHelper helper,
            DayPilotData model,
            DayPilotViewOptions options)
        {
            <strong>var</strong> calendar = <strong>new</strong> DayPilotCalendar();
            <strong>if</strong> (model != null)
            {
                model.CopyTo(calendar);
            }
            <strong>if</strong> (options != null)
            {
                options.CopyTo(calendar);
            }
            <strong>var</strong> sb = <strong>new</strong> System.Text.StringBuilder();
            sb.Append("&lt;div class=\"dayPilot\"&gt;"); // allows working around td cellpadding bug in css
            <strong>using</strong> (<strong>var</strong> sw = <strong>new</strong> System.IO.StringWriter(sb))
            {
                <strong>using</strong> (<strong>var</strong> tw = <strong>new</strong> HtmlTextWriter(sw))
                {
                    calendar.RenderControl(tw);
                }
            }
            sb.Append("&lt;/div&gt;");
            <strong>return</strong> sb.ToString();
        }</code></pre>
</blockquote>
<p>Note the div. The current version of DayPilot astonishingly, as of this writing, does not put a class anywhere in its rendered markup. Since the stylesheet for the default ASP.NET MVC site conflicts with DayPilot, to some degree, I wrapped the whole control in a div so that I could fix the layout in CSS.</p>
<p>Another way which I could have used the control in ASP.NET MVC would be to register a tag prefix and use code behind/code generation, as with standard ASP.NET. I&#8217;ve registered a tag prefix in the demo solution in case you want to try that yourself. Be aware, however, that setting up codebehind and code generation files in an MVC application is somewhat less than simple; doing it right requires, among other things, manual editing of the csproj file. So I do recommend using the control in the way I&#8217;ve illustrated.</p>
<p>Finally, here&#8217;s the source code for the action which supplies data for the control. Since this is a demo solution, I&#8217;m generating random events:</p>
<blockquote>
<pre><code><strong>        public</strong> ActionResult Index()
        {
            <strong>var</strong> r = <strong>new</strong> Random();
            <strong>var</strong> q = <strong>from</strong> i <strong>in</strong> Enumerable.Range(1, 4)
                    <strong>let</strong> start = DateTime.Today.AddHours(r.Next(47))
                    <strong>select new</strong> DayPilotDataItem
                    {
                        Id = i,
                        Start = start,
                        End = start.AddHours(1),
                        Text = string.Format("Event {0}", i)
                    };
            <strong>var</strong> model = <strong>new</strong> DayPilotData
            {
                StartDate = DateTime.Today,
                Days = 2,
                Data = q
            };
            <strong>return</strong> View(model);
        }</code></pre>
</blockquote>
<p>Of course, it&#8217;s just as easy to select data from a database.</p>
<p>The current version of DayPilot has a kind of a weird limitation: You cannot make it smaller, in the vertical dimension, than 30 pixels per hour. Based on some inspection of the source code, I think this is fixable if you are comfortable altering the source. But be aware of the limitation.</p>
<p>There are more DayPilot features which I have not covered, but that should be enough to get you on your way. If you have any questions, post them in comments, and I&#8217;ll see whdat I can do to help out.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38297&amp;akst_action=share-this" onclick="akst_share('38297', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F12%2F38297%2F', 'Using+DayPilot+with+ASP.NET+MVC'); return false;" title="Post to del.icio.us, etc." id="akst_link_38297" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20DayPilot%20with%20ASP.NET%20MVC&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F12%2F38297%2F" id="akst_email_38297" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: Understanding LINQ Errors</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/05/05/38274/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/05/05/38274/#comments</comments>
    <pubDate>Tue, 05 May 2009 11:26:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38274</guid>
    <description><![CDATA[If you spend enough time with the PagedList class that I&#8217;ve been using for paging in the method which supplies data to jqGrid, it&#8217;s a near-certainty that sooner or later you will see a LINQ error with Count in the call stack. The error may seem confusing, because it has nothing to do with Count. [...]]]></description>
      <content:encoded><![CDATA[<p>If you spend enough time with the PagedList class that I&#8217;ve been using for paging in <a title="LINQ Extensions" href="http://blogs.teamb.com/craigstuntz/2009/04/15/38212/">the method which supplies data to jqGrid</a>, it&#8217;s a near-certainty that sooner or later you will see a LINQ error with Count in the call stack. The error may seem confusing, because it has nothing to do with Count. Commentor Graeme has been experimenting with <a href="/files/2009/04/griddemo_1256.zip">my demo solution</a>, and <a href="http://blogs.teamb.com/craigstuntz/2009/04/27/38243/#comment-6168">has run into just this issue</a>:</p>
<blockquote><p>Finding your blogs very helpful - superbly written - just found out about jqgrid last night and have integrated your code into my project.</p>
<p>One thing that didn’t work for me though was the dates fix above…</p>
<p>adding</p>
<p><code>.ToString(System.Globalization.CultureInfo.CurrentUICulture)</code></p>
<p>onto the end of my <code>DateTime </code>values makes everything render Ok but when I try doing a search, it fails. Debugging shows the error is</p>
<p>Method ‘<code>System.String ToString(System.IFormatProvider)</code>’ has no supported translation to SQL.</p>
<p>at the <code>TotalItemCount = source.Count();</code> line of the PagedList.cs file.</p>
<p>Any ideas?</p></blockquote>
<p>In order to understand this error, we need to remember several important things about LINQ:</p>
<ul>
<li>LINQ is lazy. Creating or modifying an IQueryable with methods like <code>Where</code>, <code>Take</code>, <code>OrderBy</code>, etc. does not actually execute the query. The query will only be executed when you call a LINQ method which requires execution to produce its results — like <code>Count</code>.</li>
<li>When a LINQ query expression includes something which looks like a method call, the method is not invoked directly. Instead, what is actually produced is an <a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"><code>Expression</code></a> representing that method. If the LINQ provider happens to be LINQ to Objects, the method will eventually be invoked when the query is executed. But if it happens to be LINQ to SQL or LINQ to Entities, the method may never be invoked, and instead might be replaced (if possible) with equivalent SQL.</li>
<li>Most LINQ providers do not support every possible LINQ query expression. Most providers don&#8217;t even support the entire LINQ API, and only LINQ to Objects can be presumed to support all method calls on an object in a query. In some cases, <a title="Supported and Unsupported Methods (LINQ to Entities)" href="http://msdn.microsoft.com/en-us/library/bb738550.aspx">as with LINQ to Entities, this is documented</a>. With other providers, you may have to guess/experiment. Any LINQ provider which has to translate a LINQ query expression into SQL syntax can only really support methods which it is hard-coded to recognize. Worse, it is not even uncommon for providers to support one overload of a particular method but not a different overload of the same method. See, for example, the LINQ to Entities document I just linked or the <code>ToString</code> method, which is generally supported in LINQ to Entities/SQL, but has a special overload on the <code>DateTime </code>type which is not supported. Worse still, method calls may be supported in some contexts but not others. Graeme reports that LINQ to SQL accepted the <code>ToString</code> overload in the context of a <code>Select</code>, but not in the context of a <code>Where</code>. This makes sense from an implementation point of view, but means programmers have to be extraordinarily careful about what we include in our LINQ queries, especially when they are constructed dynamically.</li>
</ul>
<p>By now it should be obvious what is going on here: The particular overload of <code>ToString</code> which I used in my example is supported in LINQ to Objects but not in LINQ to SQL in a <code>Where</code> expression. My demo solution used a repository based on LINQ to Objects, so the query I showed worked correctly there. But it does not work with LINQ to SQL. Because LINQ is lazy, you will not actually see an error about this until the query is translated into SQL by the LINQ provider, and that does not happen until the call to <code>Count</code> in <code>PagedList</code>.</p>
<p>This means that when you write a LINQ query expression using LINQ to SQL, LINQ to Entities, etc., you are essentially working in a partially dynamic language. Unless you study the documentation very, very carefully, you will not know for certain until runtime if your query will be accepted by the provider.</p>
<p>So how could we work around this problem?</p>
<ul>
<li>Use a different method or a different overload which is supported by the LINQ provider used in your project. This is fine if an appropriate method/overload exists.</li>
<li>Give up on doing the formatting in C# and use JavaScript instead. This will work, but it&#8217;s a bit like using beheading to cure acne. C# is, after all, a general-purpose programming language. We should not have to give up on formatting a date.</li>
<li>Bring the query into LINQ to Objects using a method such as <code>AsEnumerable</code>. Obviously, we would want to apply the paging and ordering first. In this method, we would execute one query (using LINQ to SQL or something) which would retrieve an ordered list of records for the specified page, using <code>AsEnumerable</code> to transform the results into a List. We would then execute a LINQ to Objects query against this list in order to perform the formatting. This will actually work OK, although it can end up being a good bit of code to write for what should be a fairly simple task.</li>
<li>Write a new LINQ provider which understands the method in question. This seems like an enormous amount of work, but I&#8217;ll include it for completeness.</li>
<li>Separate the concerns of serialization and querying. You can tell by the 50-cent words that this is the solution I prefer. <img src='http://blogs.teamb.com/feeds/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Remember, the original query worked just fine. It is only the serialization to JavaScript which caused unexpected results. One way to fix this is to hide the members which are problematic to serialize and replace them with a string version of same:</p>
<blockquote>
<pre><code><strong>private class</strong> JavaScriptDateFixer
{
    [NonSerialized]
    <strong>internal </strong>DateTime _date;
    <strong>public int</strong> Id { <strong>get; set; </strong>}
    <strong>public int</strong> IntProperty { <strong>get; set; </strong>}
    <strong>public string </strong>StringProperty { <strong>get; set</strong>; }
    <strong>public string </strong>DateProperty { <strong>get </strong>{ <strong>return </strong>_date.ToString(System.Globalization.CultureInfo.CurrentUICulture); } }
}

<strong>public</strong> ActionResult GridDemoData(<strong>int </strong>page, <strong>int </strong>rows,<strong> string </strong>search, <strong>string </strong>sidx, <strong>string </strong>sord)
{
    <strong>var </strong>repository = <strong>new </strong>Repository();
    <strong>var </strong>model = <strong>from </strong>entity <strong>in </strong>repository.SelectAll().OrderBy(sidx + " " + sord)
                <strong>select new </strong>JavaScriptDateFixer
                {
                    Id = entity.Id,
                    IntProperty = entity.IntProperty,
                    StringProperty = entity.StringProperty,
                    _date = entity.DateProperty
                };
    <strong>return </strong>Json(model.ToJqGridData(page, rows, <strong>null</strong>, search,
        <strong>new</strong>[] { "IntProperty", "StringProperty", "DateProperty" }));
}
</code></pre>
</blockquote>
<p>Note that even though this code looks quite different, this does almost exactly the same thing as the code I&#8217;ve replaced. The only real difference is that I&#8217;ve delayed the call to ToString until after the query is executed. That&#8217;s enough to keep LINQ to SQL or LINQ to Entities happy.</p>
<p>So with this fix is everything fine? Maybe. I really like LINQ; I think it&#8217;s an extraordinarily powerful tool. But here we have hit upon what I consider to be the single biggest problem with LINQ. The combination of very limited support for all possible query expressions in common LINQ providers like LINQ to SQL and building queries dynamically can be very dangerous. Unless you test all possible query permutations, you cannot be completely confident that any query you build will actually execute successfully. In typical dynamic language programming, you mitigate this problem by writing unit tests. But unit tests are not supposed to connect to a database. Unfortunately, the limitation here is that the point of translation to SQL. So any unit test which mocked the LINQ provider, say, using LINQ to Objects or some other in-memory representation would not actually encounter the limitations we are trying to test.</p>
<p>I have yet to see a really good solution for unit testing LINQ to SQL or LINQ to Entities, one which would combine the desired attributes of not actually connecting to the database while surfacing any potential problems in SQL generation. I suspect that such a beast may never exist for LINQ to SQL, but for LINQ to Entities it seems at least possible. One could write an Entity Framework provider which returns mocked instances of entities. Any LINQ syntax not understood by the Entity Framework would be caught before the mock provider was ever invoked. This is a feature I would like to see in a future version of the Entity Framework.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38274&amp;akst_action=share-this" onclick="akst_share('38274', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F05%2F38274%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+Understanding+LINQ+Errors'); return false;" title="Post to del.icio.us, etc." id="akst_link_38274" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20Understanding%20LINQ%20Errors&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F05%2F05%2F38274%2F" id="akst_email_38274" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>jQuery Index Inconsistency</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/30/38271/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/30/38271/#comments</comments>
    <pubDate>Thu, 30 Apr 2009 12:15:02 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38271</guid>
    <description><![CDATA[The jQuery :nth-child selector has an "index" argument which is 1-based. But the jQuery "index" method, which is arguably the converse of the selector, returns a 0-based result. This is very easy to work around once you&#8217;re aware of it, but it&#8217;s surprising in a library which is, generally, designed both well and consistently.
Share This [...]]]></description>
      <content:encoded><![CDATA[<p>The jQuery <a title="      * Main Page     * Downloading jQuery     * How jQuery Works     * FAQ     * Tutorials     * Using jQuery with Other Libraries     * Variable Types  API Reference      * jQuery Core     * Selectors     * Attributes     * Traversing     * Manipulation     * CSS     * Events     * Effects     * Ajax     * Utilities     * jQuery UI  Plugins      * Plugin Repository     * Authoring  Support      * Mailing List and Chat     * Submit New Bug  About jQuery      * Contributors     * History of jQuery     * Sites Using jQuery     * Browser Compatibility     * Licensing     * Donate  Toolbox      * What links here     * Related changes     * Upload file     * Special pages     * Printable version     * Permanent link  Views      * Article     * Discussion     * Edit     * History  Personal tools      * Log in / create account  Selectors/nthChild" href="http://docs.jquery.com/Selectors/nthChild#index">:nth-child selector has an "index" argument which is 1-based</a>. But the jQuery "index" method, which is arguably the converse of the selector, <a title=" Core/index" href="http://docs.jquery.com/Core/index#subject">returns a 0-based result</a>. This is very easy to work around once you&#8217;re aware of it, but it&#8217;s surprising in a library which is, generally, designed both well and consistently.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38271&amp;akst_action=share-this" onclick="akst_share('38271', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F30%2F38271%2F', 'jQuery+Index+Inconsistency'); return false;" title="Post to del.icio.us, etc." id="akst_link_38271" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=jQuery%20Index%20Inconsistency&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F30%2F38271%2F" id="akst_email_38271" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: Deleting Records</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/29/38266/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/29/38266/#comments</comments>
    <pubDate>Wed, 29 Apr 2009 15:46:48 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38266</guid>
    <description><![CDATA[This is the fifth post in a series on using jqGrid with ASP.NET MVC. Today, we’re going to begin examining the grid&#8217;s editing features by implementing deletes. If you’re new to the series, you might want to start at the beginning.
The delete feature of jqGrid is, oddly, almost entirely undocumented, even though there quite a [...]]]></description>
      <content:encoded><![CDATA[<p>This is the fifth post in a series on using jqGrid with ASP.NET MVC. Today, we’re going to begin examining the grid&#8217;s editing features by implementing deletes. If you’re new to the series, you might want to start at <a title="Introduction" href="/craigstuntz/2009/04/14/38200/">the beginning</a>.</p>
<p>The delete feature of jqGrid is, oddly, almost entirely undocumented, even though there quite a few examples of different methods of <a href="http://www.secondpersonplural.ca/jqgriddocs/index.htm">editing</a>, and inserts are documented, to a lesser extent. But it does exist; I just had to read the source code to figure out how it works.</p>
<p>JqGrid has three different methods of editing data. The cell edit feature allows the user to edit a single cell the grid at a time, and saves the data when the cell loses focus. The row edit feature works similarly, but does not save the data until the row loses focus. The form edit feature shows a modal dialog instead of editing the values inline. Of these three, the form edit feature is the only one which supports deletes. However, you can still use one of the other "modes" for editing, if you like. Just be aware that when you do a delete, you will be in the form edit code. Also, deletes won&#8217;t work if you change the grid&#8217;s configuration to disable the form edit feature.</p>
<p>In order to allow the user to delete a row, I need to:</p>
<ul>
<li>Add a delete button to the grid&#8217;s toolbar. I could, of course, use a custom button or something instead of the grid&#8217;s toolbar if I chose to do so.</li>
<li>Specify a URL for the delete action</li>
<li>Implement a delete action on the controller</li>
</ul>
<p>I can accomplish the first two tasks by making a slight change to the JavaScript that configures the grid:</p>
<blockquote><p><code>}).<a href="http://www.secondpersonplural.ca/jqgriddocs/_2er0j2mvk.htm">navGrid</a>(pager, { edit: false, add: false, del: <strong>true</strong>, search: false }<strong>, {}, {}, {url: "Delete"}</strong>);</code></p></blockquote>
<p>I&#8217;ve highlighted the parts I&#8217;ve changed in boldface. Changing the "<code>del</code>" property to true turns on the toolbutton. The fifth argument is an object specifying options for the delete action, of which I have only specified the URL. This is important: The only places you can specify the URL for delete are in the arguments to the <code>delGridRow</code> method or in the toolbar&#8217;s configuration. There is not a "delete URL" property of the grid itself.</p>
<p>If you don&#8217;t specify a delete URL in this way, the grid will presume that you want to send delete requests to the URL you have specified for editing rows. There will be an "<code>oper</code>” value in the submitted form indicating that the request is a delete rather than an edit. But I prefer to use a separate URL for delete, because I think that fits more naturally in the ASP.NET MVC paradigm.</p>
<p>Now let&#8217;s write an action to handle the delete:</p>
<blockquote>
<pre><code>[AcceptVerbs(HttpVerbs.Post)]
<strong>public </strong>ActionResult Delete(<strong>int </strong>id)
{
    <strong>var </strong>repository = <strong>new </strong>Repository();
    <strong>var </strong>deleted = repository.Delete(id);
    <strong>if </strong>(!deleted)
    {
        Response.StatusCode = 500;
        <strong>return </strong>Content("Record not found.");
    }
    <strong>return </strong>Json(true);
}</code></pre>
</blockquote>
<p>Again, I&#8217;ll note that I&#8217;m using a mock repository for this demo so that you can compile and run the solution without needing to set up a database. Since the mock repository is based on IList, the Delete method of the repository returns a Boolean indicating whether or not the requested record was found, since that is how IList behaves. It would probably be more correct to return a partial view in the event of an error rather than specifying the contents directly, but error handling is a subject I hope to cover in more depth later on. For the time being, simply changing the StatusCode will tell the grid when something does not work.</p>
<p>If the delete was successful, I return "true." By default, the grid ignores returned data when the operation is successful. However, you can handle the grid&#8217;s afterSubmit event, which will be passed any data you do return. So what you choose to return, and what you do with it, is entirely up to you.</p>
<p>With all that in place, deletes work as expected. I&#8217;m not going to update the demo solution just yet, because I&#8217;ll be covering edits and inserts <a href="http://catb.org/jargon/html/R/Real-Soon-Now.html">real soon now</a>. But first I need to <a title="Understanding LINQ Errors" href="http://blogs.teamb.com/craigstuntz/2009/05/05/38274/">revisit formatting and explain more about LINQ</a>".</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38266&amp;akst_action=share-this" onclick="akst_share('38266', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F29%2F38266%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+Deleting+Records'); return false;" title="Post to del.icio.us, etc." id="akst_link_38266" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20Deleting%20Records&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F29%2F38266%2F" id="akst_email_38266" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: Search and Formatting</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/27/38243/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/27/38243/#comments</comments>
    <pubDate>Mon, 27 Apr 2009 12:44:54 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38243</guid>
    <description><![CDATA[This is the fourth post in a series on using jqGrid with ASP.NET MVC. Today, we&#8217;re going to examine search and formatting results. I will implement a search feature and fix the problem with formatting date columns which I observed in the last post. I&#8217;ve updated the demo solution with these new features, and also [...]]]></description>
      <content:encoded><![CDATA[<p>This is the fourth post in a series on using jqGrid with ASP.NET MVC. Today, we&#8217;re going to examine search and formatting results. I will implement a search feature and fix the problem with formatting date columns which I observed in <a title="Finally, A Solution" href="http://blogs.teamb.com/craigstuntz/2009/04/17/38229/">the last post</a>. I&#8217;ve updated the <strong><a href="/files/2009/04/griddemo_1256.zip">demo solution</a></strong> with these new features, and also fixed <a href="http://blogs.teamb.com/craigstuntz/2009/04/17/38229/#comment-5754">a bug reported by <span class="comment-author vcard"><span class="fn n">Andrey</span></span></a> last time. If you&#8217;re new to the series, you might want to start at <a title="Introduction" href="http://blogs.teamb.com/craigstuntz/2009/04/14/38200/">the beginning</a>.</p>
<p>First, let&#8217;s fix the date display. The reason the <a href="http://blogs.teamb.com/files/2009/04/jqgriddemoapp1_1192.png">date appeared so oddly</a> is that there is no official support for Date types in JSON, even though JavaScript has a date type. Microsoft, therefore, invented their own way of encoding dates for their JSON serializer, which jqGrid does not understand. There are two possible ways to fix the problem. The first is to keep sending the data to the grid in the Microsoft format, and write a <a href="http://www.secondpersonplural.ca/jqgriddocs/_2kn0mlo1p.htm">custom formatter for the grid</a> to parse that into a human-readable string. The second is to change the data we send to the grid. Both ways work, but I&#8217;m going to demonstrate the second method, mostly because I find C#&#8217;s date handling features superior to (<a title="date basics" href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-date-basics/">and less confusing than</a>) JavaScript&#8217;s.</p>
<p>In order to change the date "column" in the results of the query to a formatted string, we simply need to project into an anonymous type. However, this would break the sort, because a text sort on a formatted date will not be in the correct order. Hence, it is necessary to apply the sort before projecting. So I add an OrderBy to the query, and pass null as the <code>orderBy</code> argument to the <code>ToJqGridData</code> method.</p>
<blockquote>
<pre><code><strong>public </strong>ActionResult GridDemoData(<strong>int </strong>page, <strong>int </strong>rows, <strong>string </strong>search, <strong>string </strong>sidx, <strong>string </strong>sord)
{
    <strong>var </strong>repository = <strong>new </strong>Repository();
    <strong>var </strong>model = <strong>from </strong>entity <strong>in </strong>repository.SelectAll().OrderBy(sidx + " " + sord)
                <strong>select new</strong>
                {
                    Id = entity.Id,
                    IntProperty = entity.IntProperty,
                    StringProperty = entity.StringProperty,
                    DateProperty = entity.DateProperty.ToString(
                        System.Globalization.CultureInfo.CurrentUICulture)
                };
    <strong>return </strong>Json(model.ToJqGridData(page, rows, <strong>null</strong>, search,
        <strong>new</strong>[] { "IntProperty", "StringProperty", "DateProperty" }));
}</code></pre>
</blockquote>
<p>Note that in this revised solution I&#8217;ve updated the mock repository to return more sensible dates.</p>
<p><strong>Important update:</strong> This code works correctly with LINQ to Objects, as with my demo repository, but will not work with LINQ to SQL. <a title="Understanding LINQ Errors" href="http://blogs.teamb.com/craigstuntz/2009/05/05/38274/">I have addressed this issue in a subsequent post</a>.</p>
<p>Now let&#8217;s add a search feature. One of the problems in making a "demo" search is that search is a highly application-specific feature, both in terms of implementation and in terms of user experience. JqGrid&#8217;s search feature presumes that you want a search which looks something like this:</p>
<p><a href="/files/2009/04/jqgridsearchform_1250.png"><img src="/files/2009/04/jqgridsearchform_1250.png" alt="" width="411" height="61" /></a></p>
<p>Visually, there are lots of variations on this theme available, but in terms of the use case they all presume that the user will specify which fields she would like to search. However, I prefer a "Google-style" interface with just a search box and an implementation that can (hopefully) figure out what the user actually wants. So that&#8217;s what I&#8217;m going to demonstrate. The needs of your application may be different. The important thing to take away from this demonstration is that the jqGrid search feature can be co-opted to fit <em>your </em>design.</p>
<p>I want the search box to appear above the grid at all times, rather than requiring the user to press a toolbutton to see it. So first I need to add an empty div to the markup in order to indicate where the search box will be positioned, relative to the grid:</p>
<blockquote>
<pre><code>    &lt;h2&gt;GridDemo&lt;/h2&gt;
    &lt;div id="search"&gt;&lt;/div&gt;
    &lt;table id="grid" class="scroll" cellpadding="0" cellspacing="0"&gt;&lt;/table&gt;
    &lt;div id="pager" class="scroll" style="text-align:center;"&gt;&lt;/div&gt;</code></pre>
</blockquote>
<p>Next, I add a small bit of JavaScript to tell jqGrid to replace this div with a search control:</p>
<blockquote><p><code> </code></p>
<pre>    search.filterGrid("#" + grid.attr("id"), {
        gridModel: false,
        filterModel: [{
            label: 'Search',
            name: 'search',
            stype: 'text'
        }]
    });</pre>
</blockquote>
<p>The <code>filterModel </code>tells the grid to show a search control for one column, called "Search." Note that the entities I&#8217;m returning do not have a property called "search." That&#8217;s OK. When the user types something in the search box and presses enter, the grid will add a query string parameter to its request for the data of the form "<code>search=WhatTheUserTyped</code>". That&#8217;s what I want, and the fact that there is no "search" column in the data does not adversely affect the grid in any way.</p>
<p>The first argument to <code>filterGrid </code>is a little odd. I&#8217;m required to pass a jQuery selector as a string rather than being able to pass a jQuery object directly. Since this is all inside a method which accepts jQuery objects as arguments (rather than hard-coding the IDs of the DOM objects in the method, for unit-testability), I have to "decode" the jQuery object into a selector string. But note that I did not need to do that when setting up the pager or the grid itself. Like I said before, the grid&#8217;s API is consistently inconsistent.</p>
<p>As you can see in the code at the beginning of this post, the GridDemoData action just passes the search query string parameter through to the ToJqGridData method unchanged. Inside that method, I use Dynamic LINQ to alter the IQueryable to implement the search. I&#8217;ve cleaned up this method substantially since I first posted the code. Here&#8217;s the revised method:</p>
<blockquote><p><code> </code></p>
<pre><em>/// &lt;summary&gt;
/// Adds a Where to a Queryable list of entity instances.  In other words, filter the list
/// based on the search parameters passed.
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;Entity type contained within the list&lt;/typeparam&gt;
/// &lt;param name="baseList"&gt;Unfiltered list&lt;/param&gt;
/// &lt;param name="searchQuery"&gt;Whatever the user typed into the search box&lt;/param&gt;
/// &lt;param name="searchColumns"&gt;List of entity properties which should be included in the
/// search.  If any property in an entity instance begins with the search query, it will
/// be included in the result.&lt;/param&gt;
/// &lt;returns&gt;Filtered list.  Note that the query will not actually be executed until the
/// IQueryable is enumerated.&lt;/returns&gt;</em>
<strong>private static </strong>IQueryable&lt;T&gt; ListAddSearchQuery&lt;T&gt;(
    IQueryable&lt;T&gt; baseList,
    <strong>string </strong>searchQuery,
    IEnumerable&lt;<strong>string</strong>&gt; searchColumns)
{
    <strong>if </strong>((String.IsNullOrEmpty(searchQuery)) | (searchColumns == null)) <strong>return </strong>baseList;
    <strong>const string</strong> strpredicateFormat = "{0}.ToString().StartsWith(@0)";
    <strong>var </strong>searchExpression = <strong>new </strong>System.Text.StringBuilder();
    <strong>string </strong>orPart = String.Empty;
    <strong>foreach </strong>(<strong>string </strong>column <strong>in </strong>searchColumns)
    {
        searchExpression.Append(orPart);
        searchExpression.AppendFormat(strpredicateFormat, column, searchQuery);
        orPart = " OR ";
    }
    <strong>var </strong>filteredList = baseList.Where(searchExpression.ToString(), searchQuery);
    <strong>return </strong>filteredList;
}</pre>
</blockquote>
<p>Importantly, this method is simply adding to the expression represented by the IQueryable. It does not actually implement the search. So any search methodology which understands LINQ can deal with its results. At least, theoretically. In practice, LINQ providers vary greatly in terms of which LINQ features they support. So although this method works fine with LINQ to Objects (as used in the rest of the demo solution) I cannot guarantee that it will work with every LINQ provider in the world. You have to try, and revise it to fit the capabilities of the provider you&#8217;re using.</p>
<p>Putting all these pieces together, I now have a search feature which does what I want:</p>
<p><a href="/files/2009/04/jqgridwithsearch_1253.png"><img src="/files/2009/04/jqgridwithsearch_1253.png" alt="" width="457" height="132" /></a><br />
Be sure to <strong><a href="/files/2009/04/griddemo_1256.zip">download the updated solution</a></strong> in order to get the bug fixes and new features.</p>
<p>As a special, no-extra-charge bonus, the updated solution also includes a demonstration of using the grid&#8217;s tree view mode with client-side data from a JavaScript function. This has nothing to do with ASP.NET MVC; it&#8217;s just an example of how to use a grid feature which I wrote in response to <a href="http://www.trirand.com/blog/?page_id=18/treegrid/empty-treegrid-with-client-side-data/page-1/post-6175/#p6175">a request in the jqGrid support forums</a>.</p>
<p>That&#8217;s all for today. <a title="Deletes" href="http://blogs.teamb.com/craigstuntz/2009/04/29/38266/">In the next post in the series, I&#8217;ll begin to demonstrate the grid&#8217;s editing features</a>, and how to use them in an ASP.NET MVC application. But I will also take requests. If there&#8217;s a grid feature you&#8217;d like to see demonstrated query question regarding using the grid in ASP.NET MVC, please feel free to make a request in comments, and I will answer it as best I can.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38243&amp;akst_action=share-this" onclick="akst_share('38243', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F27%2F38243%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+Search+and+Formatting'); return false;" title="Post to del.icio.us, etc." id="akst_link_38243" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20Search%20and%20Formatting&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F27%2F38243%2F" id="akst_email_38243" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>A Crash Course In Failure</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/23/38241/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/23/38241/#comments</comments>
    <pubDate>Thu, 23 Apr 2009 10:37:39 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38241</guid>
    <description><![CDATA[My new article, A Crash Course In Failure, has just been published on the architecture site NPlus1. In it, I examine the surprisingly persuasive argument that unplugging entire racks of live, production servers is not only a good idea, but that shutting them down any other way is a mistake, and what this means for [...]]]></description>
      <content:encoded><![CDATA[<p>My new article, <a href="http://nplus1.org/articles/a-crash-course-in-failure/">A Crash Course In Failure</a>, has just been published on the architecture site NPlus1. In it, I examine the surprisingly persuasive argument that unplugging entire racks of live, production servers is not only a good idea, but that shutting them down any other way is a mistake, and what this means for how we design software.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38241&amp;akst_action=share-this" onclick="akst_share('38241', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F23%2F38241%2F', 'A+Crash+Course+In+Failure'); return false;" title="Post to del.icio.us, etc." id="akst_link_38241" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=A%20Crash%20Course%20In%20Failure&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F23%2F38241%2F" id="akst_email_38241" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Embarcadero Jobs and jqGrid Trees</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/20/38238/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/20/38238/#comments</comments>
    <pubDate>Mon, 20 Apr 2009 12:37:14 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Delphi]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38238</guid>
    <description><![CDATA[I have a couple of short updates on topics I&#8217;ve covered recently.
On The Podcast at Delphi.org, Nick Hodges confirms my earlier speculation about reorganization in the "CodeGear" group at Embarcadero. The whole show is worth listening to. Congratulations are due to Chris Pattinson, who was promoted to Director of Quality for all of Embarcadero. Time [...]]]></description>
      <content:encoded><![CDATA[<p>I have a couple of short updates on topics I&#8217;ve covered recently.</p>
<p>On The Podcast at Delphi.org, <a title="27 - Nick Hodges - R&amp;D Manager" href="http://www.delphi.org/2009/04/27-nick-hodges-rd-manager/">Nick Hodges confirms</a> my earlier <a title="Embarcadero Development Tools Reorganization?" href="http://blogs.teamb.com/craigstuntz/2009/04/16/38223/">speculation about reorganization in the "CodeGear" group at Embarcadero</a>. The whole show is worth listening to. Congratulations are due to <a href="http://blogs.embarcadero.com/chrispattinson/">Chris Pattinson</a>, who was promoted to Director of Quality for all of Embarcadero. Time to update the subtitle of your blog, Chris! (And maybe even write a post or two&#8230;) Sounds like good changes all around. You read it here first, folks!</p>
<p>I wrote <a href="http://www.trirand.com/blog/?page_id=18/treegrid/empty-treegrid-with-client-side-data/page-1/post-6175/#p6175">a short demo showing how to use jqGrid in tree grid node with client-side data</a> supplied by a JavaScript function.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38238&amp;akst_action=share-this" onclick="akst_share('38238', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F20%2F38238%2F', 'Embarcadero+Jobs+and+jqGrid+Trees'); return false;" title="Post to del.icio.us, etc." id="akst_link_38238" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Embarcadero%20Jobs%20and%20jqGrid%20Trees&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F20%2F38238%2F" id="akst_email_38238" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: Finally, A Solution</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/17/38229/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/17/38229/#comments</comments>
    <pubDate>Fri, 17 Apr 2009 14:07:35 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Uncategorized]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38229</guid>
    <description><![CDATA[Having introduced jqGrid and written LINQ extension methods to make supplying data to the grid easy, we&#8217;re now ready to put together a demo application. The solution I&#8217;m going to build demonstrates sorting and paging. In a future post, I will enhance it to demonstrate search, formatting, and editing data. I&#8217;ve made the demo application [...]]]></description>
      <content:encoded><![CDATA[<p>Having <a href="http://blogs.teamb.com/craigstuntz/2009/04/14/38200/">introduced jqGrid</a> and written <a href="http://blogs.teamb.com/craigstuntz/2009/04/15/38212/">LINQ extension methods</a> to make supplying data to the grid easy, we&#8217;re now ready to put together a demo application. The solution I&#8217;m going to build demonstrates sorting and paging. In a future post, I will enhance it to demonstrate search, formatting, and editing data. I&#8217;ve made the demo application available for download, but be advised that I intend to update it in the next few days; it&#8217;s currently a work in progress.</p>
<p>Rather than make you set up the Northwind database, I&#8217;ve written a quick, mock repository which supplies random data for the application. But the data persists for the lifetime of the app, so I&#8217;ll be able to demonstrate sorting, paging, etc. This way you can just run the application, without having to set up SQL Server.</p>
<p>So let&#8217;s write some code display a grid.</p>
<p>The data I&#8217;m going to display in the grid is a fairly useless type:</p>
<blockquote>
<pre><code>    <strong>public class </strong>SomeEntity
    {
        <strong>public int </strong>Id { <strong>get; set; </strong>}
        <strong>public int </strong>IntProperty { <strong>get; set; </strong>}
        <strong>public string </strong>StringProperty { <strong>get; set</strong>; }
        <strong>public </strong>DateTime DateProperty { <strong>get; set; </strong>}
    }</code></pre>
</blockquote>
<p>We need two actions. The first will display the page containing the grid. The second supplies data for one page of the grid. Remember, the grid can page through large datasets. It will only request one page of data at a time.</p>
<pre><code>        <strong>public </strong>ActionResult GridDemo()
        {
            <strong>return </strong>View();
        }

        <strong>public </strong>ActionResult GridDemoData(<strong>int </strong>page, <strong>int </strong>rows, <strong>string </strong>search, <strong>string </strong>sidx, <strong>string </strong>sord)
        {
            <strong>var </strong>repository = <strong>new </strong>Repository();
            <strong>var </strong>model = repository.SelectAll().ToJqGridData(page, rows, sidx + " " + sord, search,
                <strong>new</strong>[] { "IntProperty", "StringProperty", "DateProperty" });
            <strong>return </strong>Json(model);
        }</code></pre>
<p>The first action simply returns a view containing the HTML table which will eventually become the grid. It doesn&#8217;t need a model, because the grid will request its data asynchronously. The second action handles the data requested by the grid.</p>
<p>In order to make this work, we need HTML elements for the grid and its pager in the view, along with a reference to the JavaScript which will turn those elements into the grid.</p>
<blockquote>
<pre><code>&lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
    &lt;h2&gt;GridDemo&lt;/h2&gt;
    &lt;table id="grid" class="scroll" cellpadding="0" cellspacing="0"&gt;&lt;/table&gt;
    &lt;div id="pager" class="scroll" style="text-align:center;"&gt;&lt;/div&gt;
&lt;/asp:Content&gt;

&lt;asp:Content ID="Script" ContentPlaceHolderID="ScriptContent" runat="server"&gt;
    &lt;script language="javascript" type="text/javascript" src="&lt;%= Url.Content("~/Scripts/Home.GridDemo.js") %&gt;"&gt;&lt;/script&gt;
&lt;/asp:Content&gt;</code></pre>
</blockquote>
<p>The JavaScript file is where the grid itself is configured.</p>
<blockquote>
<pre><code>$(document).ready(<strong>function</strong>() {
    GridDemo.Home.GridDemo.setupGrid($("#grid"), $("#pager"));
});

GridDemo.Home.GridDemo = {
    setupGrid: <strong>function</strong>(grid, pager) {
        grid.jqGrid({
            colNames: ['Int', 'String', 'Date'],
            colModel: [
                        { name: 'IntProperty', index: 'IntProperty' },
                        { name: 'StringProperty', index: 'StringProperty' },
                        { name: 'DateProperty', index: 'DateProperty' },
                      ],
            pager: pager,
            sortname: 'IntProperty',
            rowNum: 10,
            rowList: [10, 20, 50],
            sortorder: "asc",
            url: "GridDemoData"
        }).navGrid(pager, { edit: <strong>false</strong>, add: <strong>false</strong>, del: <strong>false</strong>, search: <strong>false </strong>});
    }
};</code></pre>
</blockquote>
<p>Important to note here are:</p>
<ul>
<li><code>colNames</code>, the grid column captions the user sees.</li>
<li><code>colModel</code>,which includes the property <code>name</code>, which is the field name in the returned JSON data which supplies the data for that column, and <code>index</code>, which is the name which will be sent to the <code>GridDemoData </code>action as the <code>sidx </code>(field name to sort on) argument when you click on a grid header. There are a number of other properties you can set here which control editing, with, formatting, etc. See <a href="http://www.secondpersonplural.ca/jqgriddocs/_2eb0fihps.htm">the documentation</a> for full details. Importantly, <code>colNames </code>and <code>colModel </code>must have the same number of entries, and be in the same order.</li>
<li><code>url</code>, which tells the grid where to get its data. You&#8217;ll notice that the value I&#8217;ve passed is the name of the second action.</li>
</ul>
<p>As I mentioned in <a title="LINQ Extensions" href="http://blogs.teamb.com/craigstuntz/2009/04/15/38212/">the last post</a>, I set a number of the grid options in a script referenced by the Site.Master, in order to prevent having to set them on every grid I create. The configuration idea for the grid on an individual page should be only the things that are unique to that page. So there is a fair bit of configuration for the grid which is not included here. In addition, the Site.Master contains references to the grid&#8217;s JavaScript and CSS files.</p>
<p>Finally, it&#8217;s worth mentioning that when you add jqGrid to a project you need to edit the jQuery.jqGrid.js file to tell the grid where to find the rest of the JS files it needs. Once you look at this file, it is obvious what you need to change.</p>
<p>At this point, I&#8217;m going to make the demo application available for download, so that you can experiment with it yourself. However, I&#8217;ll caution that I intend to update it when I write the next post in this series. In other words, the current download is a work in progress. It will change in the next few days.</p>
<p><a href="/files/2009/04/griddemo_1256.zip">Download the Solution (587 KB)</a></p>
<p>So let&#8217;s run the solution and see what we get:</p>
<p><a href="/files/2009/04/jqgriddemoapp1_1192.png"><img src="/files/2009/04/jqgriddemoapp1_1192.png" alt="jqGrid demo app version 1" width="500" height="464" /></a><br />
OK, the hideous and eyestrain-inducing clash between the default MVC theme and the jQuery UI "lightness" theme included with the grid download notwithstanding, this is actually not bad. Sorting and paging both work, and performance is very good.</p>
<p>But what&#8217;s the deal with the data in that date column? It turns out that there is no standard representation of a date in JSON, so Microsoft invented their own. The grid doesn&#8217;t know about this special format. <a title="Search and Formatting" href="http://blogs.teamb.com/craigstuntz/2009/04/27/38243/">We&#8217;ll clean that up in the next post in this series and also cover search. </a>Stay tuned!</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38229&amp;akst_action=share-this" onclick="akst_share('38229', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F17%2F38229%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+Finally%2C+A+Solution'); return false;" title="Post to del.icio.us, etc." id="akst_link_38229" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20Finally%2C%20A%20Solution&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F17%2F38229%2F" id="akst_email_38229" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Embarcadero Development Tools Reorganization?</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/16/38223/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/16/38223/#comments</comments>
    <pubDate>Thu, 16 Apr 2009 10:44:35 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Delphi]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38223</guid>
    <description><![CDATA[Item 1:
Nick Hodges has a new role/job title.
Item 2:
During his presentation to the Columbus Architecture Group a couple of weeks ago, Mike Rozlog handed out business cards which gave his title as "Senior Project Manager, Java Tools." He told us that in a couple of days he would have new business cards, because his role [...]]]></description>
      <content:encoded><![CDATA[<h5>Item 1:</h5>
<p><a href="http://blogs.embarcadero.com/nickhodges/2009/04/14/39230">Nick Hodges has a new role/job title.</a></p>
<h5>Item 2:</h5>
<p>During <a href="http://blogs.teamb.com/craigstuntz/2009/04/06/38188/">his presentation to the Columbus Architecture Group</a> a couple of weeks ago, Mike Rozlog handed out business cards which gave his title as "Senior Project Manager, Java Tools." He told us that in a couple of days he would have new business cards, because his role was changing. He didn&#8217;t tell us precisely what the new role would be, but I got the feeling that, like Nick, he was happy with the change.</p>
<p>Now, it is of course possible that these two changes happening so close together is merely a coincidence. But my <em><strong>personal speculation</strong></em> is that there are bigger plans afoot, and I&#8217;m glad to see that Mike and Nick, two people I trust, seem to be happy with them.</p>
<p>Repeat: <em>This is just my personal speculation</em>. It is based on the evidence above, not inside information. I could be wrong.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38223&amp;akst_action=share-this" onclick="akst_share('38223', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F16%2F38223%2F', 'Embarcadero+Development+Tools+Reorganization%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38223" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Embarcadero%20Development%20Tools%20Reorganization%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F16%2F38223%2F" id="akst_email_38223" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: LINQ Extensions</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/15/38212/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/15/38212/#comments</comments>
    <pubDate>Wed, 15 Apr 2009 11:25:36 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38212</guid>
    <description><![CDATA[Mere hours after I posted the first in a planned series of posts on using jqGrid in ASP.NET MVC applications, Phil Haack, a rather-more-widely-read-ASP.NET-MVC-blogger, wrote a long post on, er, exactly the same thing. Who, me, bitter? Naahhh…  
But it turns out that we&#8217;re using the grid in a different way, and I think [...]]]></description>
      <content:encoded><![CDATA[<p>Mere hours after I posted <a title="Introduction" href="http://blogs.teamb.com/craigstuntz/2009/04/14/38200/">the first in a planned series of posts on using jqGrid in ASP.NET MVC applications</a>, Phil Haack, a rather-more-widely-read-ASP.NET-MVC-blogger, wrote <a title="Using jQuery Grid With ASP.NET MVC" href="http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx">a long post on, er, exactly the same thing</a>. Who, me, bitter? Naahhh… <img src='http://blogs.teamb.com/feeds/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But it turns out that we&#8217;re using the grid in a different way, and I think the difference is important. So rather than just referring you to Phil&#8217;s post and skipping the rest of the series, I think I still have some important information to contribute. In particular, I&#8217;m using the grid in a way which allows me to write an extension method for <code>IQueryable&lt;T&gt;</code> which returns data suitable for the grid, without having to know anything about the type <code>T</code>. If you look closely at the code in Phil&#8217;s post, you will see that populating the cell array requires custom code (or use of reflection) every time you want to return data to a grid.</p>
<p>It&#8217;s important to me that the method should work without knowing anything about the type of the data in the list because I don&#8217;t want to have to write repetitious code in every action method which supplies data to a grid to shape the data according to the grid&#8217;s needs, and because I generally use anonymous types for JSON serialization. JSON cannot handle object graphs with cycles (i.e., a "circle" of objects which all reference each other). The .NET JSON serializer will throw an exception if you pass it an object which contains a circular reference, or refers to another object which does. Since this is largely data-dependent and, worse, can be occasionally masked by lazy loading and the like, the safest way to serialize to JSON is to pass it data which provably can never contain a cycle. Anonymous types work really well for this. I&#8217;ll probably elaborate on this point in a future post. For the time being, the important thing is that I need to be able to take any IQueryable and turn it into data suitable for the grid, without having to think about what type that list might contain.</p>
<p><strong>In a nutshell, this is what I want to be able to do:</strong></p>
<blockquote>
<pre><code><strong>public </strong>JsonResult ListGridData(<strong>int </strong>page, <strong>int </strong>rows, <strong>string </strong>search, <strong>string </strong>sidx, <strong>string </strong>sord)
{
    <strong>var </strong>model = repository.SelectAll().ToJqGridData(page, rows, sidx + " " + sord, search,
      <strong>new</strong>[] { "Column1", "</code><code>Column2</code><code>", "</code><code>Column3</code><code>" })
    <strong>return </strong>Json(model);
}</code></pre>
</blockquote>
<p>In this example, <code>repository.SelectAll()</code> returns an <code>IQueryable&lt;TSomething&gt;</code>. I&#8217;ve written a method, <code>ToJqGridData</code>, which can transform that <code>IQueryable</code> into data suitable for the grid without having to know what <code>TSomething</code> is. (What the heck is that string array? Don&#8217;t worry about that just yet; I&#8217;ll cover it in a little bit.) The argument names aren&#8217;t what I would have picked, but they come from the grid. There is probably a way to change them, but I&#8217;ve never bothered to look.</p>
<p>The key to this is a grid property called <code>jsonReader.repeatitems</code>. I&#8217;m not sure why it&#8217;s called <code>repeatitems</code>, but here&#8217;s what it does. When <code>repeatitems </code>is true (the default), data is returned to the grid in a "cell array," like in Phil&#8217;s post. That is, an individual row of data in the JSON looks like this:</p>
<blockquote>
<pre>{id:<span class="codestring">"1"</span>, cell:[<span class="codestring">"cell11"</span>, <span class="codestring">"cell12"</span>, <span class="codestring">"cell13"</span>]}</pre>
</blockquote>
<p>When <code>repeatitems </code>is false, the data looks like a regular object in JSON format:</p>
<blockquote>
<pre>{id:<span class="codestring">"45678"</span>,name:<span class="codestring">"Speakers"</span>,note:<span class="codestring">"note"</span>,stock:<span class="codestring">"false"</span>,ship:<span class="codestring">"4"</span>}</pre>
</blockquote>
<p>Interestingly, it turns out that <em>this is the format the .NET JSON serializer already uses</em>. So I don&#8217;t have to write <em>any </em>code to get this portion of the data into the right shape. I just hand an object to the JSON serializer and let it do its thing. The only things I need to do to make the data work for the grid is to handle paging, sorting, search, and provide certain other bits of data, like the number of rows.</p>
<p>But, as you may have noticed, I&#8217;m lazy. Why write code when someone else has already done it? <a title="PagedList&lt;T&gt;" href="http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/">Rob Conery wrote a decent type for paging eons ago</a>, and <a title="PagedList Strikes Back" href="http://www.squaredroot.com/post/2008/07/08/PagedList-Strikes-Back.aspx">Troy Goode enhanced it</a>. So I&#8217;m going to use their work instead of re-writing paging. It turns out this type already computes most of what the grid needs to know. And Microsoft has this thing called Dynamic LINQ which can deal with ordering and filtering by property names, mostly. All I have to do is tie this stuff together.</p>
<p>I wrote a type to hold the data which the grid needs. You can actually use an anonymous type for this; the JavaScript grid obviously doesn&#8217;t care if the data it receives comes from an anonymous type or not, but because I am writing extension methods to IQueryable, it was convenient for me to have a non-anonymous type so that the extension methods could build on each other. This type represents one page of data requested by the grid:</p>
<blockquote>
<pre><code><strong>namespace </strong>GridDemo.Models
{
<em>    /// &lt;summary&gt;
    /// This type is designed to conform to the structure required by the JqGrid JavaScript component.
    /// It has all of the properties required by the grid. When this type is serialized to JSON, the resulting
    /// JSON will be in the structure expected by the grid when it fetches pages of data via AJAX calls.
    /// &lt;/summary&gt;</em>
    [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Jq",
        Justification = "JqGrid is the correct name of the JavaScript component this type is designed to support.")]
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Jq",
        Justification = "JqGrid is the correct name of the JavaScript component this type is designed to support.")]
    <strong>public class</strong> JqGridData
    {
<em>        /// &lt;summary&gt;
        /// The number of pages which should be displayed in the paging controls at the bottom of the grid.
        /// &lt;/summary&gt;</em>
        <strong>public int </strong>Total {<strong> get; set;</strong> }
</code><em><code>        /// &lt;summary&gt;
</code><code>        /// The current page number which should be highlighted in the paging controls at the bottom of the grid.
</code></em><code><em>        /// &lt;/summary&gt;</em>
</code><code>        <strong>public int </strong>Page { <strong>get; set;</strong> }
</code><em><code>        /// &lt;summary&gt;
</code><code>        /// The total number of records in the entire data set, not just the portion returned in Rows.
</code></em><code><em>        /// &lt;/summary&gt;</em>
</code><code>        <strong>public int </strong>Records { <strong>get; set; </strong>}</code><code>
</code><em><code>        /// &lt;summary&gt;
</code><code>        /// The data that will actually be displayed in the grid.
</code></em><code><em>        /// &lt;/summary&gt;</em>
</code><code>        <strong>public </strong>IEnumerable Rows { <strong>get; set; </strong>}
</code><em><code>        /// &lt;summary&gt;
</code><code>        /// Arbitrary data to be returned to the grid along with the row data. Leave null if not using. Must be serializable to JSON!
</code></em><code><em>        /// &lt;/summary&gt;</em>
</code><code>        <strong>public object </strong>UserData { <strong>get; set; </strong>}</code><code>
</code><code>    }
}</code></pre>
</blockquote>
<p>Note that I&#8217;ve used C# capitalization for the property names. This is not what the grid expects. But I have to tell the grid that I&#8217;m using a non-default value for <code>repeatitems </code>anyway, so it&#8217;s nice to follow C# conventions.</p>
<p>We have lots of grids in our application, so rather than configuring each grid individually, we set defaults for the grid in one place. In a JavaScript file referenced by the Site.Master, this method is called in the jQuery ready event:</p>
<blockquote>
<pre><code>    setDefaults: <strong>function</strong>() {
        $.jgrid.defaults = $.extend($.jgrid.defaults, {
            datatype: 'json',
            height: 'auto',
            imgpath: '/Content/jqGrid/themes/basic/images',
            jsonReader: {
                root: "Rows",
                page: "Page",
                total: "Total",
                records: "Records",
                repeatitems: <strong>false</strong>,
                userdata: "UserData",
                id: "Id"
            },
            loadui: "block",
            mtype: 'GET',
            multiboxonly: <strong>true</strong>,
            rowNum: 20,
            rowList: [10, 20, 50],
            url: "ListGridData.json",
            viewrecords: <strong>true</strong>
        });
    }</code></pre>
</blockquote>
<p>In addition to setting <code>repeatitems</code>, telling the grid to expect the capitalization I mentioned above, this code also sets the grid theme and other options we want to be consistent throughout the application. One important property set in the <code>jsonReader </code>property is <code>id</code>. The value supplied is the name of a column in the returned data which contains a unique ID for the row. You can supply any name you want to, and the type of the property can be just about anything serializable, but it is important that the data you return to the grid contains some unique ID. All of the types in our Entity Framework model contain a unique ID called "<code>Id</code>", so we set this in our defaults for the grid. If you don&#8217;t have a single operating name for any data you might supply to the grid, you will have to set this value on the individual grids, when you write the JavaScript for the view.</p>
<p>Now I can write a method which takes a PagedList and transforms it into jqGrid data:</p>
<blockquote>
<pre><code>        /// &lt;summary&gt;
        /// Converts a paged list into a format suitable for the JqGrid component, when
        /// serialized to JSON. Use this method when returning data that the JqGrid component will
        /// fetch via AJAX. Take the result of this method, and then serialize to JSON. This method
        /// will also apply paging to the data.
        /// &lt;/summary&gt;
        /// &lt;typeparam name="T"&gt;The type of the element in baseList. Note that this type should be
        /// an anonymous type or a simple, named type with no possibility of a cycle in the object
        /// graph. The default JSON serializer will throw an exception if the object graph it is
        /// serializing contains cycles.&lt;/typeparam&gt;
        /// &lt;param name="list"&gt;The list of records to display in the grid.&lt;/param&gt;
        /// &lt;param name="userData"&gt;Arbitrary data to be returned to the grid along with the row data.
        /// Leave null if not using. Must be serializable to JSON!&lt;/param&gt;
        /// &lt;returns&gt;A structure containing all of the fields required by the JqGrid. You can then call
        /// a JSON serializer, passing this result.&lt;/returns&gt;
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Jq",
            Justification = "JqGrid is the correct name of the JavaScript component this type is designed to support.")]
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Jq",
            Justification = "JqGrid is the correct name of the grid component we use.")]
        <strong>public static </strong>JqGridData ToJqGridData&lt;T&gt;(<strong>this </strong>PagedList&lt;T&gt; list, <strong>object </strong>userData)
        {
            <strong>return new </strong>JqGridData()
            {
                Page = list.PageIndex,
                Records = list.TotalItemCount,
                Rows = from record in list
                       select record,
                Total = list.PageCount,
                UserData = userData
            };
        }</code></pre>
</blockquote>
<p>That&#8217;s getting somewhere, but it&#8217;s not yet enough to let me write the action method I showed above. For that, I need to wrap up the PagedList inside the action so that I can pass the arguments from the grid directly, without having to construct a new PagedList inside of every action method which supplies data to a grid. So I build on the method above:</p>
<pre><code>        /// &lt;summary&gt;
        /// Converts a queryable expression into a format suitable for the JqGrid component, when
        /// serialized to JSON. Use this method when returning data that the JqGrid component will
        /// fetch via AJAX. Take the result of this method, and then serialize to JSON. This method
        /// will also apply paging to the data.
        /// &lt;/summary&gt;
        /// &lt;typeparam name="T"&gt;The type of the element in baseList. Note that this type should be
        /// an anonymous type or a simple, named type with no possibility of a cycle in the object
        /// graph. The default JSON serializer will throw an exception if the object graph it is
        /// serializing contains cycles.&lt;/typeparam&gt;
        /// &lt;param name="baseList"&gt;The list of records to display in the grid.&lt;/param&gt;
        /// &lt;param name="currentPage"&gt;A 1-based index indicating which page the grid is about to display.&lt;/param&gt;
        /// &lt;param name="rowsPerPage"&gt;The maximum number of rows which the grid can display at the moment.&lt;/param&gt;
        /// &lt;param name="orderBy"&gt;A string expression containing a column name and an optional ASC or
        /// DESC. You can, separate multiple column names as with SQL.&lt;/param&gt;
        /// &lt;param name="searchQuery"&gt;The value which the user typed into the search box, if any. Can be
        /// null/empty.&lt;/param&gt;
        /// &lt;param name="searchColumns"&gt;An array of strings containing the names of properties in the
        /// element type of baseList which should be considered when searching the data for searchQuery.&lt;/param&gt;
        /// &lt;param name="userData"&gt;Arbitrary data to be returned to the grid along with the row data. Leave
        /// null if not using. Must be serializable to JSON!&lt;/param&gt;
        /// &lt;returns&gt;A structure containing all of the fields required by the JqGrid. You can then call
        /// a JSON serializer, passing this result.&lt;/returns&gt;
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Jq",
            Justification = "JqGrid is the correct name of the JavaScript component this type is designed to support.")]
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Jq",
            Justification = "JqGrid is the correct name of the grid component we use.")]
        <strong>public static </strong>JqGridData ToJqGridData&lt;T&gt;(<strong>this </strong>IQueryable&lt;T&gt; baseList,
            <strong>int </strong>currentPage,
            <strong>int </strong>rowsPerPage,
            <strong>string </strong>orderBy,
            <strong>string </strong>searchQuery,
            IEnumerable&lt;<strong>string</strong>&gt; searchColumns,
            <strong>object </strong>userData)
        {
            <strong>var </strong>filteredList = ListAddSearchQuery(baseList, searchQuery, searchColumns);
            <strong>var </strong>pagedModel = <strong>new </strong>PagedList&lt;T&gt;(filteredList.OrderBy(orderBy), currentPage, rowsPerPage);
            <strong>return </strong>pagedModel.ToJqGridData(userData);
        }</code></pre>
<p>Now you see that string array (IEnumerable, actually) again. JqGrid supports sorting and searching, and so do I. Like Phil, I suggest using Microsoft Dynamic LINQ in order to take the field names that jqGrid passes and turn them into a sorted, filtered, result set. ListAddSearchQuery is a (longish) method which takes a search string and a list of columns to search and turns them into a Dynamic LINQ expression and applies it to the base list. Unfortunately, search is kind of application-specific. In some applications you might want to search different columns in different ways. Some applications might want "Google-style" searching. It kind of depends upon what you&#8217;re doing. So although I will supply the source code for this method when I make the demo project available, I cannot promise that it will be useful for <em>your </em>application. Feel free to substitute your own method here.</p>
<p>It turns out both methods (the one which takes a <code>PagedList </code>and the one which takes an <code>IQueryable</code>) are useful. Generally, I use the method which takes an <code>IQueryable</code>. But every once in a while I want to do something to the data I&#8217;m about to supply to the grid before the grid sees it, but after paging, like transform a single page of results in some way. In this case, the action builds up a <code>PagedList</code>, uses that to reduce to one page of data, modifies the results in whatever way is appropriate, and then calls the <code>PagedList </code>extension. I&#8217;ve also written additional overloads to both methods which do not have a <code>userData </code>argument, since it is very seldomly used. <code>userData</code>, as the name suggests, is an additional bit of data you can return to the grid with your result set for use in grid event handlers when loading a fresh page of data. Since it&#8217;s of type object, you can put as much data in there as you need to, so long as it&#8217;s serializable to JSON. In practice, though, we rarely use this feature of the grid.</p>
<p>With these methods, it is easy to write actions as concise as the code I showed at the beginning of this post. Just get a list from somewhere and call ToJqGridData, passing information about which page to display, how to sort, etc.</p>
<p>In a future post, I will tie this all together into a demo application.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38212&amp;akst_action=share-this" onclick="akst_share('38212', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F15%2F38212%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+LINQ+Extensions'); return false;" title="Post to del.icio.us, etc." id="akst_link_38212" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20LINQ%20Extensions&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F15%2F38212%2F" id="akst_email_38212" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Using jqGrid with ASP.NET MVC: Introduction</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/14/38200/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/14/38200/#comments</comments>
    <pubDate>Tue, 14 Apr 2009 11:28:03 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38200</guid>
    <description><![CDATA[This is the first post in a short series on using the jqGrid jQuery plug-in with ASP.NET MVC. In this short introduction I will describe the plug-in, list some of its strengths and weaknesses, and explain why we selected it for our MVC applications. In the next few days, I will give detailed information about [...]]]></description>
      <content:encoded><![CDATA[<p>This is the first post in a short series on using the <a href="http://www.trirand.com/blog/">jqGrid</a> jQuery plug-in with ASP.NET MVC. In this short introduction I will describe the plug-in, list some of its strengths and weaknesses, and explain why we selected it for our MVC applications. In the next few days, I will give detailed information about how to use the grid in your own applications.</p>
<p>jqGrid provides a nice-looking grid with built-in features such as sorting, editing, search, drill-down, tree lists, and more. It is based upon jQuery and integrates well with ASP.NET MVC. <a href="http://www.trirand.com/blog/?page_id=154">The grid is dual-licensed under both the GPL and MIT licenses</a> (just like jQuery), so it can fit well into both commercial and open-source projects.</p>
<p><a href="/files/2009/04/jqgrid_1166.png"><img src="/files/2009/04/jqgrid_1166.png" alt="jqGrid with sub-grid" width="660" height="277" /></a></p>
<p>If you want to display tabular (grid) data with paging in an ASP.NET MVC application, there are essentially three choices:</p>
<ol>
<li>You can write your own grid components using HTML tables, links, manually-implemented paging, etc. This is actually less work than it might seem at first, and the first release of our ASP.NET MVC software did just this. But our own implementation lacked some of the visual flair of some of the third-party components, and avoided solving some of the harder problems, like in-line editing. Still, it was much easier than I expected, and worked well enough for our initial release.</li>
<li>You can use a commercial component designed for ASP.NET. However, many commercial grid components don&#8217;t work well with MVC. Telerik has MVC demos available for their grid, and Developer Express has said that they intend to support MVC to some degree in the future. Even when the commercial components do support MVC at all, they don&#8217;t tend to make all of their features available in MVC applications, owing to the fundamental difference between the way ASP.NET MVC and "plain" ASP.NET work. If you are building a Web application on ASP.NET MVC, I would never recommend buying an ASP.NET component unless the vendor for that component is fully committed to supporting MVC. <em>You cannot presume that any given ASP.NET component will work at all with MVC unless the vendor explicitly supports this.</em></li>
<li>You can use a grid component which has no knowledge of ASP.NET at all. There are quite a number of these, generally built within the framework of one of the popular JavaScript libraries, and it is, ironically, easier to use one of them within ASP.NET MVC application than it is to use a grid component designed for ASP.NET (but not necessarily MVC).</li>
</ol>
<p>As I said, we ended up choosing jqGrid. We were strongly influenced by the fact that we already use jQuery extensively in our application. There are several grid plug-ins available for jQuery. jqGrid has a number of advantages over the others I&#8217;ve seen, however:</p>
<ul>
<li>Supports three different models for editing data within the grid: Single-cell editing, in-line row editing, and editing within a pop-up form.</li>
<li>Unlike some of the other jQuery grid plug-ins, jqGrid has <a href="http://www.secondpersonplural.ca/jqgriddocs/index.htm">decent documentation</a> and <a href="http://trirand.com/jqgrid/jqgrid.html">a large number of demos with source code</a>.</li>
<li>You can display a simple grid, a "sub grid" (drill down), or a treeview.</li>
<li>AJAX paging is supported in a number of different formats, including JSON, XML, or JavaScript objects via a custom function.</li>
<li>The grid is updated very regularly, and <a href="http://www.trirand.com/jqgrid35/jqgrid.html">a new version, with support for the jQuery UI theming library</a> is under active development right now.</li>
<li>Tracing through the grid source code is quite easy to do with Firebug, which is useful for figuring out things which aren&#8217;t quite covered by the documentation.</li>
</ul>
<p>The grid also has a few downsides:</p>
<ul>
<li>The API is a bit of a mess. Capitalization (significant, in JavaScript) is so varied that it seems almost random. Portions of the code were clearly written by different people with limited collaboration with the original author of the grid. There is no consistent naming convention, and similar functionality is sometimes invoked in wildly different ways. For example, you set the grid height with a custom method, <code>setGridHeight</code>, instead of the jQuery method <code>height</code>. But you reload the grid&#8217;s data with a jQuery method, <code>trigger</code>, passing the string <code>"reloadGrid"</code> as an argument. It&#8217;s a good thing the grid has decent documentation and includes source code, because you&#8217;re going to need them. The API is just not discoverable.</li>
<li>Although the grid has quite a number of options for editing, it doesn&#8217;t necessarily play well with some of the other tools you may want to use in the context of editing, such as <a title="http://blogs.teamb.com/craigstuntz/2009/01/15/37923/" href="http://blogs.teamb.com/craigstuntz/2009/01/15/37923/">jQuery validation</a>. (For starters, the in-line row editing doesn&#8217;t actually use an HTML form.) The three different editing modes (single-cell, in-line row editing, and editing in a form) use different source modules, different configuration options, and work differently. Doing editing in a way not explicitly supported by the grid can be challenging.</li>
<li>Variable names in the source code use a lot of single letter and two letter abbreviations. This is quite common in JavaScript libraries, but it does make the source code a bit challenging to read.</li>
<li>Although <a href="http://www.trirand.com/blog/?page_id=154">there is both free and paid support available</a>, there is not a commercial company standing behind the grid. So don&#8217;t expect round-the-clock support, a toll-free phone number, etc.</li>
</ul>
<p>After a good deal of experimentation with several grids, we decided to use jqGrid because it has considerably more features than every other grid we examined (when used in MVC application), and because we didn&#8217;t find any of its limitations to be show stoppers.</p>
<p>The next post in this series is <a href="http://blogs.teamb.com/craigstuntz/2009/04/15/38212/">LINQ Extensions</a>. There, I show an extension method for <code>IQueryable&lt;T&gt;</code> which returns data suitable for the grid, without having to know anything about the type <code>T.</code></p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38200&amp;akst_action=share-this" onclick="akst_share('38200', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F14%2F38200%2F', 'Using+jqGrid+with+ASP.NET+MVC%3A+Introduction'); return false;" title="Post to del.icio.us, etc." id="akst_link_38200" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Using%20jqGrid%20with%20ASP.NET%20MVC%3A%20Introduction&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F14%2F38200%2F" id="akst_email_38200" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Do You Recognize Math When You See It?</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/07/38190/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/07/38190/#comments</comments>
    <pubDate>Tue, 07 Apr 2009 10:34:14 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38190</guid>
    <description><![CDATA[Jeff Atwood says:
On the other hand, I have not found in practice that programmers need to be mathematically inclined to become great software developers.  Quite the opposite, in fact. This does depend heavily on what kind of code you&#8217;re writing, but the vast bulk of code that I&#8217;ve seen consists mostly of the "balancing [...]]]></description>
      <content:encoded><![CDATA[<p><a title="Should Competent Programmers be &quot;Mathematically Inclined&quot;?" href="http://www.codinghorror.com/blog/archives/001249.html">Jeff Atwood says</a>:</p>
<blockquote><p>On the other hand, <strong>I have not found <em>in practice</em> that programmers need to be mathematically inclined to become great software developers</strong>.  Quite the opposite, in fact. This does depend heavily on what kind of code you&#8217;re writing, but the vast bulk of code that <em>I&#8217;ve</em> seen consists mostly of the "balancing your checkbook" sort of math, nothing remotely like what you&#8217;d find in the average college calculus textbook, even.</p>
<pre>{
  i = j++ / (x + v);
}</pre>
<p>Not exactly the stuff mathletes are made of.</p></blockquote>
<p>Arithmetic is one kind of math. It is relatively common in elementary math classes, and <em>relatively </em>uncommon in programming. Does Jeff&#8217;s example look like the "vast bulk of code <em>you&#8217;ve </em>seen?" It certainly doesn&#8217;t look like the vast bulk of code <em>I&#8217;ve </em>seen.</p>
<p>On the other hand, I do see a good bit of:</p>
<ul>
<li>Relational database queries (<a href="http://www.vocw.edu.vn/content/m10536/latest/">relational algebra</a>)</li>
<li>LINQ (<a href="http://mathworld.wolfram.com/Functor.html">functors</a>)</li>
<li>Composition of lambda expressions (<a href="http://mathworld.wolfram.com/LambdaCalculus.html">lambda calculus</a>, of course)</li>
<li>Set operations and logical operators (<a href="http://mathworld.wolfram.com/SetTheory.html">set theory</a>)</li>
<li>Etc.</li>
</ul>
<p>That&#8217;s by no means a comprehensive list. For example, every general-purpose programming language I&#8217;ve ever used would not exist without the <a href="http://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis">Church-Turing thesis</a>. But I didn&#8217;t include that, since most people don&#8217;t do programming language design.</p>
<p>All programmers work with mathematical systems day in and day out, whether we recognize them or not. Perhaps the ability to recognize math when we see it will help us better evaluate the importance of understanding it.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38190&amp;akst_action=share-this" onclick="akst_share('38190', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F07%2F38190%2F', 'Do+You+Recognize+Math+When+You+See+It%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38190" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Do%20You%20Recognize%20Math%20When%20You%20See%20It%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F07%2F38190%2F" id="akst_email_38190" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Reminder: Mike Rozlog to Speak to Columbus Architecture Group</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/04/06/38188/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/04/06/38188/#comments</comments>
    <pubDate>Mon, 06 Apr 2009 15:28:29 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38188</guid>
    <description><![CDATA[Mike Rozlog, the product manager for the JBuilder and 3rdRail products for Embarcadero, will be speaking to the Columbus Architecture Group tonight at 6:00 p.m., on the subject of software archaeology. For more information on the topic, here is a slide deck for one of his previous presentations on the subject, and here&#8217;s a video [...]]]></description>
      <content:encoded><![CDATA[<p><a href="http://blogs.embarcadero.com/michaelrozlog/">Mike Rozlog</a>, the product manager for the JBuilder and 3rdRail products for <a href="http://www.embarcadero.com/">Embarcadero</a>, will be speaking to the <a href="http://www.colarc.org/2009/03/guest-speaker-at-april-6th-meeting.html">Columbus Architecture Group <em>tonight </em>at 6:00 p.m.</a>, on the subject of <a href="http://www.embarcadero.com/solutions/software_archeology.php">software archaeology</a>. For more information on the topic, here is <a href="http://blogs.embarcadero.com/files/2007/12/radstudiowebinar_192.pdf">a slide deck for one of his previous presentations on the subject</a>, and <a href="http://cc.embarcadero.com/Item/26427">here&#8217;s a video replay</a>.</p>
<p><strong>Update:</strong> Attendee Bill Melvin wrote <a title="COLARC Meeting - April 2009" href="http://www.bluecog.com/blog/2009/04/07/colarc-meeting-april-2009/">a short summary of the presentation</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38188&amp;akst_action=share-this" onclick="akst_share('38188', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F06%2F38188%2F', 'Reminder%3A+Mike+Rozlog+to+Speak+to+Columbus+Architecture+Group'); return false;" title="Post to del.icio.us, etc." id="akst_link_38188" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Reminder%3A%20Mike%20Rozlog%20to%20Speak%20to%20Columbus%20Architecture%20Group&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F04%2F06%2F38188%2F" id="akst_email_38188" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Designed as Designer</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/31/38153/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/31/38153/#comments</comments>
    <pubDate>Tue, 31 Mar 2009 13:04:52 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[General Software Development]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38153</guid>
    <description><![CDATA[Have you ever ridden a horse? When you drive the car, the process goes something like this:

Decide where you want to go.
Aim the car in that direction.
Get there.

It&#8217;s different when you ride a horse. In that case the process is more like:

Decide where you want to go.
Communicate your intention to the horse.
Arrive at some hybrid [...]]]></description>
      <content:encoded><![CDATA[<p>Have you ever ridden a horse? When you drive the car, the process goes something like this:</p>
<ol>
<li>Decide where you want to go.</li>
<li>Aim the car in that direction.</li>
<li>Get there.</li>
</ol>
<p>It&#8217;s different when you ride a horse. In that case the process is more like:</p>
<ol>
<li>Decide where you want to go.</li>
<li>Communicate your intention to the horse.</li>
<li>Arrive at some hybrid of where you want to go and where the horse wants to go.</li>
<li>Return to step (1). Repeat.</li>
</ol>
<p>Now, which of those two would you find more analogous to software architecture? Does that sound like a silly question? The reason that I ask is that I read a paper last night which argues in a persuasive but decidedly unconventional manner that <em>the things you design </em>have, for lack of a better word, intention. In other words, building a cathedral, or a software application is more like riding a horse than driving a car.</p>
<p>The paper is called <a href="http://dreamsongs.org/DesignedAsDesigner.html">Designed as Designer</a>, by <a href="http://en.wikipedia.org/wiki/Richard_Gabriel">Richard P. Gabriel</a>. As technical papers go, this one is unusual to say the least. It was written as a response to <a href="http://www.oopsla.org/oopsla2007/index.php?page=podcasts/">an address by Fred Brooks at OOPSLA 2007</a>, during his keynote. In the address, Brooks stated:</p>
<blockquote><p>If we look back then at the 19th century and the things that happened—the cartwright and the textile machinery, Stephenson (the train), Brunel&#8217;s bridges and railway, Edison, Ford, the Wright brothers, etc.—these were very largely the designs of single designers or, in the case of the Wright brothers, pairs.</p></blockquote>
<p>Gabriel disputes this idea, and chooses an unexpected way of making his case. <a href="http://dreamsongs.org/Books.html">Gabriel is a published author </a>both in the fields of computer science and writing/poetry. The paper draws as much from his experience in the latter field as the former—there is considerably more poetry quoted in the paper than source code. He also manages to weave in, <em>with some relevance, no less</em>, baseball statistics.</p>
<p>The general outline of the paper is as follows: First, there is a running, fictional narrative about a child named Pippo who observes the construction of the <a href="http://www.duomofirenze.it/storia/storia_eng.htm">cathedral of Firenze</a>. Next, Gabriel addresses Brooks&#8217;s point directly. He discusses the relationship between poets T.S. Eliot and Ezra Pound in the evolution of Eliot&#8217;s masterpiece <a href="http://www.bartleby.com/201/1.html"><em>The Waste Land</em></a>. The middle, and longest, section of the paper is an explanation and example of a theory of poetry he has developed based around an almost algorithmic approach to classifying a given text as either poetry or ordinary writing. Contrasting an early version of a published column with a later revision to same, he asserts that the structure of the earlier version leads the poet into the later revision. I should add here that even though I really like poetry, I find his analysis a bit academic for my taste. Returning to the Cathedral of Firenze, Gabriel shows that many people were involved in its design and construction, and that the Cathedral form itself had a bigger impact on the final design than the architect. Then he uses statistical analysis of the career of Roger Maris to show that luck, as much as skill, played a role in Maris&#8217;s exceeding Babe Ruth&#8217;s home run record.</p>
<p>The final section of the paper includes, almost shockingly at this point, discussion of computer science and one small example of (Lisp) source code. He relates the story of how Gerry Sussman and Guy Steele discovered how two mechanisms they were studying turned out to be exactly the same thing by implementing both of them separately and noticing later that the source code was identical.</p>
<p>If all this sounds a bit, well, crazy, it isn&#8217;t. <a href="http://www.oopsla.org/oopsla2008/program-overview/essays.html">The paper was presented at OOPSLA 2008</a>. I&#8217;m not above a bit of <em>schadenfreude</em>, but this is definitely a "laugh with him" rather than "laugh at him" paper. If you have ever had the experience of designing a system, and then uncovering necessary changes in the system when you try to use your design, then you have some idea of what he&#8217;s getting at.</p>
<p>I am also reminded, more than a little bit, of Michael Pollan&#8217;s book, <a href="http://www.amazon.com/gp/product/0375760393?ie=UTF8&amp;tag=learningtowhi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0375760393">The Botany of Desire</a><img style="border:none !important;margin:0px !important" src="http://www.assoc-amazon.com/e/ir?t=learningtowhi-20&amp;l=as2&amp;o=1&amp;a=0375760393" border="0" alt="" width="1" height="1" />, which calls the evolution of the humans and plants "co-evolutionary," and questions who has domesticated whom. Again, we don&#8217;t tend to think of plants as having "intention," but maybe the question should be, "just what is intention, really?" So all in all, it&#8217;s a fascinating read.</p>
<p>That said, it seems to me that, to some extent, Brooks and Gabriel may be talking past each other. Surely, Brooks can&#8217;t be under the delusion that the Wright brothers invented the airplane in a vacuum? Surely, Gabriel wouldn&#8217;t presume that he is? Much of Brooks&#8217;s writing focuses on organizational support for creativity. Indeed, Brooks, to me, seems almost to take creativity as a given, more so than examining what it is and what makes it tick. Gabriel seems to be on the other side of this coin, examining the nature of creativity, rather than how to make it work in a large organization.</p>
<p>Both points of view are worth reading, I think.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38153&amp;akst_action=share-this" onclick="akst_share('38153', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F31%2F38153%2F', 'Designed+as+Designer'); return false;" title="Post to del.icio.us, etc." id="akst_link_38153" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Designed%20as%20Designer&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F31%2F38153%2F" id="akst_email_38153" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>URIs Should Be Persistent</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/30/38145/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/30/38145/#comments</comments>
    <pubDate>Mon, 30 Mar 2009 12:02:54 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38145</guid>
    <description><![CDATA[When you are creating a new URI for a site you are building, give it a lot of thought. You should aim to design a URI which can last forever. Of course, this is not news. Jakob Nielsen said it 10 years ago. But in the intervening 10 years, we&#8217;ve gone from URIs which typically [...]]]></description>
      <content:encoded><![CDATA[<p>When you are creating a new URI for a site you are building, give it a lot of thought. You should aim to design a URI which can last forever. Of course, this is not news. <a title="URL as UI" href="http://www.useit.com/alertbox/990321.html">Jakob Nielsen said it 10 years ago</a>. But in the intervening 10 years, we&#8217;ve gone from URIs which typically used to look something like this:</p>
<blockquote><p><code>http://www.example.com/foo.html</code></p></blockquote>
<p>&#8230;which is fine, because if you go to such a link, you probably really will get HTML back, to URIs which (often) look something like this:</p>
<blockquote><p><code>http://www.example.com/foo.php</code></p></blockquote>
<p>&#8230;which, <a title="The Web Is Just Text" href="http://blogs.teamb.com/craigstuntz/2009/02/16/38024/">as I noted in a previous post</a>, is a lie. Actually, it&#8217;s worse than a lie; it&#8217;s poor encapsulation. What happens when you come to your senses and stop using PHP? Now you URIs have to change, which means you get to either create redirects for that abomination or break every link to your site. One of the things we&#8217;ve learned from the success of Google is that the information encoded in the links between sites is nearly as important as the information on the sites itself.</p>
<p><em>The web is dynamic. It has to be, because it is too big to compile. </em>And so the same concerns we have when writing code and dynamic languages often apply to creating a web site, whether you use a dynamic language or not. You need to choose very good names, because if you ever need to change them you will either break stuff or have a substantial job on your hands correcting every reference to the name you&#8217;ve changed, including references you don&#8217;t personally control.</p>
<p>So I&#8217;m going to propose a general rule, which states, "<strong>Any URI which allows an informed developer to discern the technology used to serve the result is probably broken.</strong>" The resources you are serving, if they are at all valuable to the user, will probably last longer than the implementation you use to serve them.</p>
<p>Of course, choosing good names is hard. <a title="Naming is Hard" href="http://blog.stackoverflow.com/2009/03/it-stack-overflow-update-naming-is-hard/">I read a great quote the other day</a>:</p>
<blockquote><p>There are only two hard things in Computer Science: cache invalidation and naming things. -Phil Karlton</p></blockquote>
<p>Also, even after you&#8217;ve chosen a good URI, you may have to do extra work to make it functional. If routing is not built into the technology stack you&#8217;re using, you may have to implement a URL rewriter to make your persistent URIs functional. It&#8217;s worth the effort to do so.</p>
<p><strong>Late update</strong>: Thank you to commentor <a href="http://www.stecki.de/">Stecki</a> for <a href="http://blogs.teamb.com/craigstuntz/2009/03/30/38145/#comment-5058">the link to</a> the following article: <a href="http://www.w3.org/Provider/Style/URI">Cool URIs don&#8217;t change</a>, by Tim Berners-Lee. Well said.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38145&amp;akst_action=share-this" onclick="akst_share('38145', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F30%2F38145%2F', 'URIs+Should+Be+Persistent'); return false;" title="Post to del.icio.us, etc." id="akst_link_38145" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=URIs%20Should%20Be%20Persistent&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F30%2F38145%2F" id="akst_email_38145" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Why Has the Size of TObject Doubled In Delphi 2009?</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/25/38138/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/25/38138/#comments</comments>
    <pubDate>Wed, 25 Mar 2009 11:23:00 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Delphi]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38138</guid>
    <description><![CDATA[Because it has a new feature.
Mason Wheeler noticed that TObject.InstanceSize returns 8 (bytes). It turns out that this is new in Delphi 2009; in previous releases, TObject.InstanceSize returned 4. But when you look at the definition of TObject in System.pas, you don&#8217;t see any fields declared at all.
Four out of the eight bytes are consumed [...]]]></description>
      <content:encoded><![CDATA[<p>Because it has a new feature.</p>
<p><a title="TURBU" href="http://turbu-rpg.com/">Mason Wheeler</a> noticed that <a title="What data does a TObject contain?" href="http://stackoverflow.com/questions/679022/what-data-does-a-tobject-contain">TObject.InstanceSize returns 8</a> (bytes). It turns out that this is new in Delphi 2009; in previous releases, TObject.InstanceSize returned 4. But when you look at the definition of TObject in System.pas, you don&#8217;t see any fields declared at all.</p>
<p>Four out of the eight bytes are consumed by the <acronym title="Virtual Method Table">VMT</acronym>; this has been true since the first version of Delphi. You can read more about that in <a title="The Delphi Object Model" href="http://oreilly.com/catalog/delphi/chapter/ch02.html">this chapter from <em>Delphi In A Nutshell</em></a>, which is old, but still accurate insofar as the VMT is concerned.</p>
<p>But what about the remaining four bytes? I didn&#8217;t remember the answer, but I enjoy a good puzzle, so I took a closer look at the source code for TObject. While poking around in System.pas, I happened to notice the following constants:</p>
<blockquote>
<pre><code><span style="color: #008000"><em>{ Hidden TObject field info }</em></span>
hfFieldSize          = <span style="color: #0000ff">4</span>;
hfMonitorOffset      = <span style="color: #0000ff">0</span>;</code></pre>
</blockquote>
<p>OK, that explains the four bytes, but what is this used for? Searching for <code>hfFieldSize</code> yielded the answer:</p>
<blockquote>
<pre><code><strong>class function</strong> TMonitor.GetFieldAddress(AObject: TObject): PPMonitor;
<strong>begin</strong>
  Result := PPMonitor(Integer(AObject) + AObject.InstanceSize - hfFieldSize + hfMonitorOffset);
<strong>end</strong>;</code></pre>
</blockquote>
<p>So any object <em>can </em>have a reference to a TMonitor instance, and that reference is as big as a pointer on the target CPU. That reminded me of <a title="Lock my Object… Please!" href="http://blogs.embarcadero.com/abauer/2008/02/19/38856">Allen Bauer&#8217;s long series of blog posts last year on the "Delphi Parallel Library,"</a> which discuss the TMonitor class in detail. He notes:</p>
<blockquote><p>The TMonitor class<em> [...] </em>is now tied directly to any TObject instance or derivative (which means <em>any</em> instance of a Delphi <strong>class</strong>).  <em>[...] </em>For Tiburón <em>[a.k.a. Delphi 2009]</em>, you merely need to call System.TMonitor.Enter(&lt;obj&gt;); or System.TMonitor.Exit(&lt;obj&gt;); among the other related methods.</p></blockquote>
<p>The ability to lock any object is a good feature to have, especially in a multi-CPU, multi-core world. So I&#8217;m happy to spend the extra four bytes to get this feature. But I do find the implementation a bit mysterious. Why not just declare an actual field in TObject? I guess one reason would be to reduce the chance of a conflict with existing code. Another possible reason would be to enforce TMonitor&#8217;s contract; by obfuscating access to the field, you reduce the chances that an uninformed programmer performs actions on the field which break the contract. But these are just guesses. I don&#8217;t know why the Delphi team settled on this implementation. I presume they have some good reason.</p>
<p><strong>Update:</strong> In comments, <a href="http://blogs.codegear.com/abauer">Allen Bauer</a> explains <a href="http://blogs.teamb.com/craigstuntz/2009/03/25/38138/#comment-4937">the reasons for this implementation</a>:</p>
<blockquote><p>The reason for always placing the monitor reference field at the end of the object instance is mainly for backward compatibility. I didn’t want to alter the layout of objects in case there was some code out there that depended upon it. Also, by hiding the implementation the chance of inadvertent mucking with the monitor data was reduced and therefore it increased the overall safety of using it.</p>
<p>If you look closely at what happens on descendant instances, the monitor field is <strong>always </strong>the last field of the instance. This happens because the compilers (Delphi &amp; C++) ensure that the field is allocated as the last step in the process of laying out the class instance. By doing this, an object laid out in pre-Delphi 2009 will be laid out exactly the same in Delphi 2009 except there is now an extra trailing pointer-sized field.</p></blockquote>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38138&amp;akst_action=share-this" onclick="akst_share('38138', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F25%2F38138%2F', 'Why+Has+the+Size+of+TObject+Doubled+In+Delphi+2009%3F'); return false;" title="Post to del.icio.us, etc." id="akst_link_38138" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Why%20Has%20the%20Size%20of%20TObject%20Doubled%20In%20Delphi%202009%3F&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F25%2F38138%2F" id="akst_email_38138" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>InterBase 2009 Hotfix Update 2</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/23/38135/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/23/38135/#comments</comments>
    <pubDate>Mon, 23 Mar 2009 23:49:31 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38135</guid>
    <description><![CDATA[IB 2009 Hotfix Update 2 is available for download, and includes many bug fixes.
]]></description>
      <content:encoded><![CDATA[<p>IB 2009 Hotfix Update 2 is <a title="InterBase Registered User Downloads" href="http://cc.embarcadero.com/reg/interbase">available for download</a>, and includes <a title="InterBase 2009 Hotfix Update 2 Readme (version 9.0.2.369)" href="http://edn.embarcadero.com/article/39435#6ResolvedDefects">many bug fixes</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38135&amp;akst_action=share-this" onclick="akst_share('38135', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F23%2F38135%2F', 'InterBase+2009+Hotfix+Update+2'); return false;" title="Post to del.icio.us, etc." id="akst_link_38135" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=InterBase%202009%20Hotfix%20Update%202&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F23%2F38135%2F" id="akst_email_38135" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>What ASP.NET MVC Did Learn from Rails</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/23/38130/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/23/38130/#comments</comments>
    <pubDate>Mon, 23 Mar 2009 19:30:27 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38130</guid>
    <description><![CDATA[This morning, I saw two different posts from Rails developers who were newly learning ASP.NET MVC, both bemoaning the fact that ASP.NET MVC does not supply/force upon you one particular ORM. The dependency on ActiveRecord is, to my way of thinking, a shortcoming of Rails, which the Rails community is presently doing an exceptional job [...]]]></description>
      <content:encoded><![CDATA[<p>This morning, I saw two different posts from <a title=".NET MVC vs Ruby on Rails" href="http://www.tokumine.com/2009/03/21/net-mvc-vs-ruby-on-rails/">Rails developers who were newly learning ASP.NET MVC</a>, both <a title="What ASP.NET MVC Can Learn From Ruby on Rails" href="http://www.kevinwilliampang.com/post/What-ASPNET-MVC-Can-Learn-From-Ruby-on-Rails.aspx">bemoaning the fact that ASP.NET MVC does not supply</a>/force upon you one particular ORM. The <a title="Rails without ActiveRecord" href="http://blog.lathi.net/articles/2007/08/08/rails-without-activerecord">dependency on ActiveRecord</a> is, to my way of thinking, a shortcoming of Rails, <a title="Lightweight Frameworks, Again" href="http://blogs.teamb.com/craigstuntz/2008/12/26/37874/">which the Rails community is presently doing <em>an exceptional job of fixing</em></a>. The best way to learn from that mistake is to not repeat it.</p>
<p>Yes, it is true that ASP.NET MVC does not force you to use one particular ORM. Yes, that means that you&#8217;re going to have to expend some thought, and quite possibly even effort, deciding which one is appropriate for you. It will not be sufficient to read a blog post about the Entity Framework from somebody who tried it once and another blog post about NHibernate from somebody who saw a screencast about it and then conclude that there are no workable solutions in the world.</p>
<p>But it&#8217;s worth the effort, because you have a big reward in store: Whatever choice you make will work just fine with ASP.NET MVC. Because the framework has no dependencies whatsoever on any ORM, all ORMs work equally well. You get to choose the best tool for your data access needs without worrying that your web framework will reject it.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38130&amp;akst_action=share-this" onclick="akst_share('38130', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F23%2F38130%2F', 'What+ASP.NET+MVC+Did+Learn+from+Rails'); return false;" title="Post to del.icio.us, etc." id="akst_link_38130" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=What%20ASP.NET%20MVC%20Did%20Learn%20from%20Rails&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F23%2F38130%2F" id="akst_email_38130" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>Mike Rozlog to Speak to Columbus Architecture Group</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/20/38126/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/20/38126/#comments</comments>
    <pubDate>Fri, 20 Mar 2009 19:41:03 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[CodeRage]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38126</guid>
    <description><![CDATA[Mike Rozlog, the product manager for the JBuilder and 3rdRail products for Embarcadero, will be speaking to the Columbus Architecture Group on Monday, April 6, at 6:00 p.m., on the subject of software archaeology. For more information on the topic, here is a slide deck for one of his previous presentations on the subject, and [...]]]></description>
      <content:encoded><![CDATA[<p><a href="http://blogs.embarcadero.com/michaelrozlog/">Mike Rozlog</a>, the product manager for the JBuilder and 3rdRail products for <a href="http://www.embarcadero.com/">Embarcadero</a>, will be speaking to the <a href="http://www.colarc.org/2009/03/guest-speaker-at-april-6th-meeting.html">Columbus Architecture Group on Monday, April 6, at 6:00 p.m.</a>, on the subject of <a href="http://www.embarcadero.com/solutions/software_archeology.php">software archaeology</a>. For more information on the topic, here is <a href="http://blogs.embarcadero.com/files/2007/12/radstudiowebinar_192.pdf">a slide deck for one of his previous presentations on the subject</a>, and <a href="http://cc.embarcadero.com/Item/26427">here&#8217;s a video replay</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38126&amp;akst_action=share-this" onclick="akst_share('38126', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F20%2F38126%2F', 'Mike+Rozlog+to+Speak+to+Columbus+Architecture+Group'); return false;" title="Post to del.icio.us, etc." id="akst_link_38126" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Mike%20Rozlog%20to%20Speak%20to%20Columbus%20Architecture%20Group&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F20%2F38126%2F" id="akst_email_38126" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>ASP.NET Routing and ASP.NET MVC</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/18/38085/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/18/38085/#comments</comments>
    <pubDate>Wed, 18 Mar 2009 13:02:58 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Web]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38085</guid>
    <description><![CDATA[.NET 3.5 SP1 introduced ASP.NET Routing. This feature is primarily used by ASP.NET MVC and Dynamic Data. Routing is actually a very simple feature; here is what it does:

Stores a list of routes.
Translates an incoming URI into lists of values and tokens, and passes those lists to the handler specified on the route. In the [...]]]></description>
      <content:encoded><![CDATA[<p>.NET 3.5 SP1 introduced ASP.NET Routing. This feature is primarily used by ASP.NET MVC and Dynamic Data. Routing is actually a very simple feature; here is what it does:</p>
<ul>
<li>Stores a list of routes.</li>
<li>Translates an incoming URI into lists of values and tokens, and passes those lists to the handler specified on the route. In the MVC framework, this feature is used to call the appropriate Controller/Action.</li>
<li>Translates a list of values into a URI suitable for inclusion within an HTML page. In the MVC framework, this feature is most commonly used in the <code>Html.RouteLink/ActionLink</code> methods you call to generate a link in your Views.</li>
</ul>
<p>Let&#8217;s examine in more detail how MVC uses Routing, and distinguish between the features of Routing and the MVC framework.</p>
<h2>Components of a URI</h2>
<p>Consider this sample URI:</p>
<p><code>http://www.example.com:80/SiteRoot/Controller/Action?foo=A&amp;bar=B#anchor</code></p>
<p>The individual parts of the URI are:</p>
<ul>
<li>The <strong>scheme </strong>(protocol), <strong>authority </strong>(host), and <strong>port </strong>("<code>http://www.example.com:80</code>" in this sample URI). I will mostly ignore this part in the rest of the post, since Routing doesn&#8217;t deal with it, except to pass it along when necessary.</li>
<li>The <strong>path </strong>("<code>/SiteRoot/</code><code>Controller/Action</code>" in this example). Per the <a title="Generic Syntax" href="http://www.ietf.org/rfc/rfc3986.txt">URI RFC</a>, this part "serves to identify a resource&#8230;" I&#8217;ll talk about what that means in a second.</li>
<li>The <strong>query </strong>("<code>?foo=A&amp;bar=B</code>" in this example). My example uses name/value pairs is the query, because that seems to be the most common case. However, the RFC says that the query can be almost anything, and the purpose of the query is to provide a non-hierarchical means of identifying the resource requested by the user.</li>
<li>The <strong>fragment </strong>("<code>#anchor</code>" in this example). I&#8217;m going to ignore this, since Routing doesn&#8217;t deal with it.</li>
<li>I&#8217;ve omitted some stuff like username/password which is almost never used today.</li>
</ul>
<h2>MapRoute</h2>
<p>Now lets examine a simple case of adding a route to the routing system. This is from the default MVC application template:</p>
<blockquote>
<pre><code>routes.MapRoute(
    <span style="color: #ff0000">"Default"</span>,                                              <span style="color: #339966">// Route name</span>
    <span style="color: #ff0000">"{controller}/{action}/{id}"</span>,                           <span style="color: #339966">// URL with parameters</span>
    <strong>new </strong>{ controller = <span style="color: #ff0000">"Home"</span>, action = <span style="color: #ff0000">"Index"</span>, id = <span style="color: #ff0000">""</span> }  <span style="color: #339966">// Parameter defaults</span>
);</code></pre>
</blockquote>
<p>Note that <code>MapRoute </code>is actually not part of the routing system; it&#8217;s an extension method added to <code>RouteCollection </code>by ASP.NET MVC. Calling <code>MapRoute </code>will add a single route to the <code>RouteCollection</code>. Most web applications will have only one <code>RouteCollection</code>, stored in <code>System.Web.Routing.RouteTable.Routes</code>. The most important thing that <code>MapRoute </code>does is to create and pass an <code>MvcRouteHandler </code>instance when adding the route to the <code>RouteCollection</code>. This ensures that when ASP.NET handles an incoming URI which matches this route, control will be passed to the MVC framework for handling the request.</p>
<p>The second argument to <code>MapRoute </code>is named "<code>url</code>", but it&#8217;s not really a complete URL. Instead, it is a template for a fragment of a URL containing <em>a portion of</em> the path component of a URI. I say "a portion of the path" because it omits the site root, which I&#8217;ve called "<code><code>/SiteRoot</code></code>" in the example above. The site root is often empty, but it doesn&#8217;t have to be. The URIs produced by the routing system include quite a bit more than the path, however. They also include the scheme/authority (in other words, the protocol and host) and, sometimes, a query.</p>
<p>There are a number of overloads to MapRoute. In addition to the values passed in this simple example, you can also pass constraints (which I&#8217;ll discuss in a moment) and namespaces. The namespaces argument is for MVC only (it&#8217;s not used by routing) and is useful when you want to put a Controller in a place where MVC wouldn&#8217;t otherwise find it.</p>
<p>A route can also contain <code>DataTokens</code>, which are not used by the routing system, but are passed to the route handler. <code>MapRoute </code>doesn&#8217;t have an overload which includes these as an argument, and I&#8217;m not going to discuss them in this post. ASP.NET MVC uses them only to store the <code>namespaces </code>argument, discussed above.</p>
<h2>Parsing a URI</h2>
<p>Let&#8217;s examine what happens when the routing system is asked to interpret a URI submitted by the user. Importantly, the RouteCollection is ordered. So the routing system will attempt to match the routes in the collection in the order you added them. The first matching route "wins" even if a later route is a "better" match. The incoming URI is compared with the url portion of the route. If it matches, the entire URI, including the query, is tokenized. If there are any constraints on the route, these are considered.</p>
<p><em>In practice, this means that if you have a lot of routes, then you are almost guaranteed to encounter a bug, sooner or later, where the wrong route is matched to an incoming URI. The only good way to prevent this that I know of is to write unit tests for your routes.</em> Unfortunately, the name of the route is not actually part of the route itself. It is stored in a private, internal dictionary in the RouteCollection. So there is no way to write a unit test which examines the name of the route returned.</p>
<p>Let&#8217;s use the sample URI and route from earlier in this post as an example. Out of the entire URI, <code>http://www.example.com:80/SiteRoot/</code><code>Controller/Action</code><code>?foo=A&amp;bar=B#anchor</code>, the routing system is only going to examine this bit when processing an incoming URI:</p>
<p><code>/</code><code>Controller/Action</code><code>?foo=A&amp;bar=B#anchor</code></p>
<p>Does this match the url portion of the route defined above? Recall that it is defined as:</p>
<pre><code><span><span style="color: #ff0000">"{controller}/{action}/{id}"
</span></span></code></pre>
<p>Yes, it matches, because "<code>Controller</code>" can be interpreted as the "<code>{controller}</code>" portion of the <code>url</code>, "<code>Action</code>" for the "<code>{action}</code>" part, and a default value exists for the "<code>{id}</code>" portions (empty string). Note that this means that having default values in a route makes that route much more likely to "match" an incoming URI. If there are defaults for every token in a URL pattern and there are no constraints, then that route will match every incoming URI. The route shown in this post is created by the MVC framework as a "catch all" route for a new application, which contains only that route. That is why it has defaults for all of its values and no constraints; it is intended to match every incoming URI. If, on the other hand, you write a special-purpose route intended only for one particular controller or action, and you provide default values for all of the tokens, then you need to implement constraints to prevent this route for matching other controllers or actions.</p>
<p>Because the url matches, we have five values, so far, to pass as the route data. "controller" will have the value Controller, and "action" will have the value "Action". "id" will have the default value. Also, from the query, "foo" will have the value "A", and "bar" will have the value "B". Now the routing system considers any constraints on the route, but in this case, there aren&#8217;t any. Therefore, this list of values is handed to the MvcRouteHandler which was created by MapRoute.</p>
<p><em>Importantly</em>, note that all of these values are strings. The routing system only deals with URIs, which are always strings. Now, your actions on your controllers can have arguments which are not strings, and the MVC framework will attempt to coerce the strings supplied by the routing system into whatever type is specified in the method signature. But that&#8217;s a feature of the MVC framework, not of the routing system. (Yes, the <code>Values</code> property returns type <code>object</code>, but, when matching an incoming URI, the segments are always added as strings.)</p>
<p>Not all URI patterns are as simple as the default route from the standard MVC application template. You can use delimiters other than /, for example. If you have hyphens, parentheses, etc. in your <code>url </code>template, these will be matched against the incoming URI to determine if the route is a match. The following route, for example, would not match the sample URI at the top of the post, even though it contains all of the necessary tokens and has no constraints:</p>
<blockquote>
<pre><code>routes.MapRoute(
    <span style="color: #ff0000">"Parenthesized"</span>,                                        <span style="color: #339966">// Route name</span>
    <span style="color: #ff0000">"{controller}({action})({id})"</span>,                         <span style="color: #339966">// URL with parameters</span>
    <strong>new </strong>{ id = <span style="color: #ff0000">""</span> }                    <span style="color: #339966">                     // Parameter defaults</span>
);</code></pre>
</blockquote>
<p>The incoming URI contains no parentheses, so this route can&#8217;t match, because the parentheses are needed to to delimit the values for <code>controller</code> and <code>action</code>, and there are no defaults for this values.</p>
<h2>Matching a Route With an Action</h2>
<p>After a route is matched to an incoming URI, and a list of route values is created, control goes to the <code>MvcRouteHandler</code>. Now the MVC framework can invoke the action on the controller specified by the "action" and "controller" route values. Note that there is nothing special about these names/values to the routing system; they&#8217;re just two more values in the list from the routing system&#8217;s point of view. But these two names, "action" and "controller" are very important to the MVC framework, for obvious reasons.</p>
<p><code>MvcRouteHandler </code>(indirectly) calls <code>MvcHandler.ProcessRequest</code>, which constructs the controller using the <code>ControllerFactory</code>, and then calls <code>Controller.Execute</code>, which, in turn, invokes the action using the <code>ControllerActionInvoker</code>. It is at this point that the values in the route are matched against the arguments for the action. In other words, tokenizing the URI and matching those values with action arguments are two entirely separate operations. The tokenizing is done by the routing system, and the matching route values with controller action arguments is done by the MVC framework.</p>
<p>In order to invoke the action, the MVC framework needs to look at the individual arguments to the action, and match them with route values. This is performed by the model binding system.</p>
<p>Note that the name of the argument does not have to correspond to a name in the route values if the model binding system can instantiate an instance of the type of the argument from the values which do exist. For example, if the type of the argument is FormCollection, then this argument can always be passed, no matter what names are present in the route values, and no matter what the name of the argument. The model binding system knows that it can always create a FormCollection by rolling up any values in the form in the incoming POST, if there are any. If there are not, it will simply return an empty FormCollection.</p>
<p>If the action takes an argument which cannot be instantiated based on the data in the route values, that is fine, so long as the argument is nullable. If the action requires a non-nullable argument which is not in the route values, or if the route values contain a value for an argument which cannot be bound into the type of that argument, the MVC framework will throw an exception. Otherwise, the action will be invoked.</p>
<h2>Creating a URI With RouteLink</h2>
<p>Creating an "<strong>a href=</strong>" tag with <code>Html.RouteLink</code> is trivial. The routing system looks up the route by name, and populates the URI with values from the <code>RouteCollection </code>you passed. Any values in the <code>RouteCollection </code>not included in the string in the <code>url </code>argument to <code>MapRoute </code>will be added to the resulting link as query string parameters. In my view, you should always prefer <code>RouteLink </code>over <code>ActionLink</code>, whenever there is any ambiguity as to which route will be returned.</p>
<p>Again, let&#8217;s consider an example, with the route defined in the MapRoute call earlier in this post:</p>
<blockquote>
<pre><code>&lt;%= Html.RouteLink(<span style="color: #ff0000">"Link text to display on page"</span>, <span style="color: #ff0000">"Default"</span>,
    <strong>new </strong><span style="color: #339966">RouteValueDictionary</span>(<strong>new </strong>{controller = <span style="color: #ff0000">"Foo"</span>, action = <span style="color: #ff0000">"Bar"</span>, foo = <span style="color: #ff0000">"A"</span>, bar = <span style="color: #ff0000">"B"</span> })) %&gt;</code></pre>
</blockquote>
<p>With this example, the order of the routes in the <code>RouteCollection</code>, the constraints, etc., are not needed to find the matching route, because we have specified ("<code>Default</code>") directly. Since there are no tokens called "foo" and "bar" in the <code>url</code> argument we passed to <code>MapRoute</code>, these will be appended to the generated URI as query string parameters. So we end up with the sample URI at the top of this post, less the anchor, provided that the site is configured to live in /SiteRoot.</p>
<h2>Creating a URI With ActionLink</h2>
<p><code>ActionLink </code>is more complicated, because the routing system must first <em>find </em>an appropriate route, and then use that route to generate the URI. In a way, the method of finding the route is similar to the method used when parsing a URI, insofar as the first matching route "wins." But in another way, it is very different, because there is no incoming URI to use as a pattern for matching the partial template passed as the <code>url</code> argument to <code>MapRoute</code>. The only thing that the <code>url</code> argument is used for in this scenario is determining which tokens must be included, either directly, or via defaults, in order for a route to match. Let&#8217;s re-examine the same scenario considered in the RouteLink section, above, only this time using <code>ActionLink</code>. The call looks like this:</p>
<blockquote>
<pre><code>&lt;%= Html.ActionLink(<span style="color: #ff0000">"Link text to display on page"</span>, <span style="color: #ff0000">"Bar"</span>, <span style="color: #ff0000">"Foo"</span>,
    <strong>new </strong><span style="color: #339966">RouteValueDictionary</span>(<strong>new </strong>{foo = <span style="color: #ff0000">"A"</span>, bar = <span style="color: #ff0000">"B"</span> })) %&gt;</code></pre>
</blockquote>
<p>Does this match the route defined at the top of this post? Yes it does, and here&#8217;s why: That route contains three tokens in its <code>url </code>argument. They are <code>controller</code>, <code>action</code>, and <code>id</code>. I have supplied values for two of these tokens in the call to <code>ActionLink</code>, namely <code>controller </code>and <code>action</code>, via the <code>controller </code>and <code>action </code>arguments in the overload of <code>ActionLink </code>I am using here. The remaining required token, <code>id</code>, is not supplied in the <code>ActionLink </code>call at all. However, there was a default for it (empty string) in the original call to <code>MapRoute</code>, so the route matches even without an explicit value for <code>id</code>. Because <code>foo </code>and <code>bar </code>are present in the <code>RouteValueDictionary</code>, but the <code>url </code>template in the route does not contain <code>{foo}</code> or <code>{bar}</code>, these will be added to the generated URI as query string parameters. Again, the generated URI will be the sample URI at the top of this post, less the anchor, provided that the site is configured to live in /SiteRoot.</p>
<h2>Conclusions</h2>
<p>I hope this long explanation has taken some of the mystery out of what routing does. Since there&#8217;s a lot of detail above, I&#8217;m going to summarize some of the information which is important for day-to-day work.</p>
<ul>
<li>Routing and the MVC framework are distinct features. MVC knows about Routing, but Routing does not know about MVC. Routing produces a list of values, but does not assign special meaning to them. MVC signs special meaning to the controller and action values.</li>
<li>Routes include information about a portion of the path in the URI and also the query, since any token not in the path is treated as part of the query.</li>
<li>The order of routes is very important, both for parsing incoming URIs and for generating URIs with ActionLink.</li>
<li>Default values in a route will cause the route to match more incoming URIs or sets of values in a <code>RouteValueDictionary</code>. Constraints in a route will cause the route to match fewer incoming URI this or sets of values in a <code>RouteValueDictionary</code>. If there are defaults for every token in a URL pattern and there are no constraints, then that route will match every incoming URI or sets of values in a <code>RouteValueDictionary</code>. For a "catch all" route like the one in the default MVC application, it is fine for all of the tokens to have default values in for there to be no constraints. If you write a special-purpose route for a particular controller or action, however, then you should probably use constraints to prevent it from ever matching any other controller or action.</li>
<li>If you have more than one route, then you simply <em>must </em>write unit tests to ensure that the correct route is selected for all incoming URIs or values used in your calls to ActionLink.</li>
</ul>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38085&amp;akst_action=share-this" onclick="akst_share('38085', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F18%2F38085%2F', 'ASP.NET+Routing+and+ASP.NET+MVC'); return false;" title="Post to del.icio.us, etc." id="akst_link_38085" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=ASP.NET%20Routing%20and%20ASP.NET%20MVC&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F18%2F38085%2F" id="akst_email_38085" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>A Not-So-Secret Sale</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/17/38109/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/17/38109/#comments</comments>
    <pubDate>Tue, 17 Mar 2009 11:02:09 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38109</guid>
    <description><![CDATA[Upscene Productions is offering their Database Workbench Pro product for 75% off, through 28 March 2009 only. They call this the "Super Secret Sale," but since Martijn asked me to post it here, I&#8217;m not sure how much of a secret it is. Anyway, 75% off is about as cheap as you&#8217;ll ever find it, [...]]]></description>
      <content:encoded><![CDATA[<p>Upscene Productions is <a href="http://www.upscene.com/dbw_secretsupersale.php">offering their Database Workbench Pro product for 75% off</a>, through 28 March 2009 only. They call this the "Super Secret Sale," but since Martijn asked me to post it here, I&#8217;m not sure how much of a secret it is. Anyway, 75% off is about as cheap as you&#8217;ll ever find it, so if you&#8217;ve been considering buying the tool, now is a good time.</p>
<p><a href="http://www.upscene.com/products.dbw.index.php">Database Workbench</a> supports InterBase and many other DB servers. You can buy the module for one (or more) DB server only if you don&#8217;t need all of them.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38109&amp;akst_action=share-this" onclick="akst_share('38109', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F17%2F38109%2F', 'A+Not-So-Secret+Sale'); return false;" title="Post to del.icio.us, etc." id="akst_link_38109" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=A%20Not-So-Secret%20Sale&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F17%2F38109%2F" id="akst_email_38109" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
  <item>
    <title>SQL Performance Tuning Book Includes InterBase</title>
    <link>http://blogs.teamb.com/craigstuntz/2009/03/16/38097/</link>
    <comments>http://blogs.teamb.com/craigstuntz/2009/03/16/38097/#comments</comments>
    <pubDate>Mon, 16 Mar 2009 19:21:22 +0000</pubDate>
    <dc:creator>Craig Stuntz</dc:creator>
    
		<category><![CDATA[InterBase]]></category>

    <guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/?p=38097</guid>
    <description><![CDATA[SQL Performance Tuning, by Peter Gulutzan and Trudy Pelzer, "is a guide for users and programmers who want to improve SQL performance no matter what brand of SQL they use. &#8230; All the ideas have been tested against the eight leading DBMS applications."
I haven&#8217;t read this book, but someone in the newsgroups mentioned that it [...]]]></description>
      <content:encoded><![CDATA[<p><a href="http://www.pearsoned.co.uk/Bookshop/detail.asp?item=302416">SQL Performance Tuning, by Peter Gulutzan and Trudy Pelzer</a>, "is a guide for users and programmers who want to improve SQL performance no matter what brand of SQL they use. &#8230; All the ideas have been tested against the eight leading DBMS applications."</p>
<p>I haven&#8217;t read this book, but <a href="https://forums.codegear.com/thread.jspa?threadID=13638&amp;tstart=0#91911">someone in the newsgroups mentioned that it included InterBase</a>. He writes:</p>
<p style="padding-left: 30px">"Note that they tested on IB6 — but I have still found most of their advice to be valid."</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=38097&amp;akst_action=share-this" onclick="akst_share('38097', 'http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F16%2F38097%2F', 'SQL+Performance+Tuning+Book+Includes+InterBase'); return false;" title="Post to del.icio.us, etc." id="akst_link_38097" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=SQL%20Performance%20Tuning%20Book%20Includes%20InterBase&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2009%2F03%2F16%2F38097%2F" id="akst_email_38097" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
      <wfw:commentRss></wfw:commentRss>
    </item>
</channel>
</rss>
<!-- 453 queries 3.622 seconds. -->
