August 2006 - Posts - Jon Galloway

August 2006 - Posts

How NOCOUNT affects ADO.NET

A co-worker recommended we include "SET NOCOUNT ON" in all stored procedures, since it reduces the network traffic for queries. I did a bit of digging; here's my take on it:

It's probably a good general practice, but the network traffic savings would be pretty minimal in most cases. This would be more important in a case where a very high volume of SQL statements with small result sets were being run, because the rowcount information would comprise a more significant portion of the network traffic. NOCOUNT doesn't make any difference on the database load, since @@ROWCOUNT is still populated regardless of the NOCOUNT setting.

UPDATE: NOCOUNT can make a significant performance difference if you are executing a large number of SQL statements, such as in the example Scott Whigham points out in his comment or the example in this article. That's because each executed SQL statement reports completion, which can cause a lot of network traffic just to report "1 row inserted.1 row inserted. 1 row inserted." That's a very valid point, and while I do stand corrected I'd point out that it's a bit of a contrived countercase. I definitely wouldn't recommend looping inserts if there's any way you can perform a bulk or batch insert. I've recently trimmed SQL execution time for a single proc from 8 hours a few minutes by converting from looping inserts to an INSERT...SELECT statement (no, I didn't write the original proc...). The point is well taken, though - if the SQL call will execute a significant number of operations, by all means SET NOCOUNT ON.

Previously, in Classic ASP and ADO, NOCOUNT was most commonly a factor if you were checking RecordsAffected on Command.Execute(). SqlDataReader does have a RecordsAffected property, but it's rarely used since it's not populated until the datareader has iterated all the rows and the datareader is closed. There are some possible implications if you're using DataAdapters to submit changes to the database, since it uses the rows affected result to determine if the update succeeded. Probably the easiest way to check for that case is to search the codebase for SqlDataAdapter and see if the Update() method is being called.

In our case, we determined that it would be good to use on a going forward basis, but the minimal savings in network traffic didn't justify the risk of modifying existing procedures.

Tech notes if you're interested in tracing how RecordsAffected is set and used by pointing Reflector at System.Data:
System.Data.SqlClient.TdsParser.ProcessDone() sets RecordsAffected.
System.Data.Common.DbDataAdapter.UpdateRow() uses reader.RecordsAffected in determining whether to call AcceptChanges and ApplyToDataRow.

Please let me know if I got any of this wrong or you disagree with my conclusions.

Posted by Jon Galloway | 1 comment(s)
Filed under:

IE7 Standalone Launcher updated for RC1

IE7 RC1 is out, so my launcher script needed an update. You can get it here. Read the previous relase announcement here.

Note: Yousif's IE7 Standalone is a little easier to install - it automatically downloads the IE7 installation package for you. Rather than duplicate his efforts, I asked Yousif for information on what had changed with RC1 and he very graciously provided me with the complete source for his standalone, which was invaluable in releasing my RC1 version. If you like the control and transparency of bat and reg files, this should work well for you, but if you'd like an easier installation experience I recommend Yousif's IE7 Standalone. The only real difference in operation is that my registry script removes the IE version vector registry key, which lets you test IE6 and IE7 pages with conditional comments at the same time.

Microsoft should ship SubSonic (formerly called ActionPack) with Atlas

Yesterday, Phil got me to watch the SubSonic screencast (it was actually called the ASP.NET ActionPack and was since renamed). I'd seen posts about it on my main RSS feeds and had ignored it because everyone had been giving their posts titles like "ActionPack - Ruby on Rails for ASP.NET." I've watched all the ROR screencasts and have been a little underwhelmed1, so I didn't bother reading further. Big mistake.

SubSonic is one of the coolest web development things I've seen in a while. The 20 minute screencast is well worth the time, but here's the basic idea:

  1. Add a reference to the SubSonic DLL
  2. Add a few lines to your web.config - tell the ActionPack how to connect to your database, and add a block that tells ASP.NET to use the SubSonic build provider.
  3. Build.
  4. (a miracle happens)
  5. Enjoy the magic.

What do I mean by magic? Again, I'll ask you to watch the screencast rather than read my boring description, but I'll give it a shot. The SubSonic build provider gives you a full featured data access layer without adding any code to your project (unless you want it). That takes care of the biggest problem with code-gen'd DAL's - the piles of generated code files which clutter up your project and need to be kept up to date although many of them may never be used. Second cool feature: a scaffold server control which gives you the same kind of basic admin functions that ROR scaffolding provides (and a few extras, like following foreign keys for dropdowns). For example, when pointed at the infamous Northwind database, here's what you get from the following server tag (no other code required):

<cc1:Scaffold ID="Scaffold1" runat="server" TableName="Products"></cc1:Scaffold>

Aside from auto-created collection classes, there's a nice dynamic query system:

Query qry = new Query(Product.Table);
qry.Top = "10";
qry.OrderBy = OrderBy.Desc(Product.Columns.UnitPrice);
GridView1.DataSource = qry.ExecuteReader();
GridView1.DataBind();

I particularly like the column and table name structs - I commented yesterday that it would be cool if he added them to eliminate the need for string parameters; less than two hours after I posted the comment he posted a new release with that feature. That allows you to code to something like Product.Columns.UnitPrice rather than "UnitPrice", so you get both autocomplete and compile time checking. Nice!

<crazy-talk>

Here's where Dr. Jeckell's "hey, check out this neat thing" post ends and Mr. Hyde takes over... Rather than letting this languish on the list of neat tools ASP.NET bloggers talk about, Microsoft should do something out of character - they should ship SubSonic with Atlas.

Why?

Well, first, the rationale: SubSonic is a great next step in the "less code is good" philosophy of ASP.NET 2.0. At a minimum, adding SubSonic to ASP.NET would be a great bridge until DLINQ comes out. It would be great to have ASP.NET span the range from ROR "it just works" simplicity to the high end systems we all know it can do.2 Even ASP.NET superstars are admiring ROR's simplicity, and ROR is quickly becomming synonomous with Web 2.0.

Yeah, but SubSonic's out on CodePlex. That's good enough, right?

Why does Microsoft need to get involved? Why not just let it hang out on CodePlex and write a little blurb on the ASP.NET site? Because most Microsoft developers only use what's in the box. Even if the developers want to use it, their bosses or co-workers will shy away from "that crazy blogger open source stuff." DotNetNuke took years to build the following it has, and even still it's not nearly as well known as Atlas, a relative newcomer to the ASP.NET toolbox. By adding this to the Microsoft endorsed ASP.NET toolkit, millions of developers would actually start using it.

Atlas? What's that got to do with a data abstraction layer?

Well, it makes sense for a few reasons:

  1. Atlas is at just the right place in the product lifecycle. It's positioned as an official "extension" of ASP.NET. It's got the Microsoft seal of approval, but it's still a separate download at this point.
  2. SubSonic needs some AJAX glitter to fare well against ROR, and Atlas could benefit from a great Hello World demo-ready application. The two are made for eachother if you look at things from the where the web development world is at, rather than how the Microsoft development tools are positioned. The Atlas website says Atlas is a free framework for building a new generation of richer, more interactive, highly personalized cross-browser web applications. SubSonic fits in well with that description. Imagine the demo you could pull off with a zero code data abstraction layer, a scaffold in an UpdatePanel, and some Atlas controls bound to SubSonic populated datasources; imagine how efficiently you could wow a client. Atlas with SubSonic would make a killer combo.

But, isn't SubSonic an open source kind of project?

It's licensed under the Mozilla Public License, which is pretty simple - you can use, redistribute, and even sell software using MPL'd code, but if you modify the MPL'd code you have to publish your changes. It's not like the "viral" GPL, which requires that you GPL your software to make use of GPL'd code. So, to say this in English, I believe that Microsoft could bundle the SubSonic DLL with Atlas, and the most they'd need to do is include a clause in the Atlas EULA stating the SubSonic code is under the MPL and the source code is available on CodePlex. They'd be free to make any changes to SubSonic as long as they released them on CodePlex, which doesn't seem like it would be a problem.

But aren't there already better implementations of Ruby on Rails for ASP.NET?

Yeah, there's MonoRail. Watch the screencast; from what I've seen I like SubSonic a lot better. SubSonic doesn't just tack ROR onto ASP.NET, it learns from it but plays smart with the .NET framework. It leverages the build provider capability, the code behind model, the server control system, etc. Rather than taking over the project with tons of added code, it adds classes which are invisible until you use them. It seems like a MonoRail project is a MonoRail project, whereas a SubSonic project happens to use SubSonic where appropriate, and can factor it out where appropriate.

But didn't this just come out? You're nuts to be talking about shipping it!

Well, yeah. Of course Microsoft would want to review the code to make sure that it's up to snuff. However, Rob Conery (the author) is the Chief Architect of the Commerce Starter Kit for ASP.NET 2.0 and an ASP.NET MVP with a great track record. Why not contract with him for 3 months to buff it out a bit?

</crazy-talk>


1Ruby on Rails advances some great web development values, but it seems like a lot of work compared ASP.NET 2.0, especially if you're using some code-gen, ORM's, or frameworks. You're left writing a lot of markup, and it's the spaghetti code kind of markup (code meatballs mixed with HTML markup noodles) that drove me nuts with "Classic ASP" and PHP. I really like the code behind approach in ASP.NET, and I definitely prefer C# and Visual Studio.NET to Ruby and a text editor that may have ROR syntax support, but no designers. Then there's the extension story - I haven't used the ROR corelib, but it sure looks like it's a lot less powerful than the .NET framework.

2No, I'm not dissing ROR. I know it runs Basecamp and a bunch of other big applications. However, I think if you compare the feature sets of ROR and ASP.NET you'd agree that ASP.NET seems better suited for enterprise applications.


I'm having trouble posting comments, so here are my replies to the comments below:

@Colin:
1. All the ActionPack bashers are upset because it's not doing the whole ROR MVC thing. Bah. ActionPack / SubSonic isn't ROR for ASP.NET, is's a better way of doing things with ASP.NET. MonoRails has a place in the full blown MVC pattern approach to web development; I'm not knocking that. SubSonic is great because it works with and augments what ASP.NET does in the way it works.

2. Not sure what your point was about ASP.NET developers not being web developers, etc. I've done a lot of web development over the past 10+ years, and I believe that less code is generally a good thing from a maintenance perspective. Those who will only use the designer and don't understand the markup would probably benefit from a simple DAL system rather than hand writing their own code or having to set a lot of properties in various server and web controls. One nice thing about this approach is that it scales - you can quickly build out a site with SubSonic, then convert SubSonic DAL code use another form of data access (hand written / NHibernate / EntLib you name it) without any structural changes. It seems like you might be upset about the markup that ASP.NET generates, which doesn't really make sense in reference to server side data access.

3. You don't really explain yourself on the last point about enterprise development. My point is that ASP.NET has a good offering for large or complex sites (MySpace, Nasdaq, many banking systems, etc.). I'm sure ROR could potentially do those kinds of jobs, but it would take a lot more work to do and code to maintain.

@David
I never really liked the strongly typed DataSet approach. Your build provider approach to them might make that better, but I'd still much rather code against DataReaders. SubSonic's DAL gives you quite a bit more than a DataSet provides, too - dynamic query, scaffolding, etc. Regarding requiring data access, I'm not sure that's true. SubSonic could build out your DAL when it is connected, and not build it when it's disconnected. I don't know if it supports that right now, but if it doesn't it doesn't seem difficult to unwire it when you're disconnected.

@Andy
My original post just said that Microsoft should ship SubSonic, but how exactly would they do that? It's an open source project; it would look wierd to try to release it separately. So then I wrote that Microsoft should ship SubSonic with the next release or update to ASP.NET, but when will that be? Microsoft ususally doesn't push out new functionality with smaller updates, so it wouldn't be until a service pack or the next ASP.NET release, and when will that be? Then I was thinking that it needed to be something on the same level as Atlas, but since it's just one DLL, why not just drop it in Atlas?

Regarding Microsoft shipping something like Castle or another ROR framework, I'm not so sure. If they did, I'd suspect it would be a large p&p EntLib like release, which doesn't fill the same niche that SubSonic does - minimal code to get data on the screen.

@Scott
BLINQ looks cool, but a command line generator is not near as clean as a build provider. Also, it looks like it generates a lot of code [ http://forums.asp.net/thread/1346141.aspx ]; SubSonic builds the DAL without adding the code to your project. Maybe BLINQ should add a build provider?

San Diego User Group (8/22/06) - Toolbox Meeting

On Tuesday I was one of several presenters at the San Diego .NET User Group's second annual Toolbox meeting. The presentations were supposed to be "rapid-fire (15 – 20 minutes), brief presentations", but I kind of took it to the extreme. I presented eleven of my favorite tools in under 18 minutes.

I was shooting for something like Scott Hanselman's presentation for GrokTalks - Ten Utilities in 10 Minutes (WMV download), but even at 100 seconds per utility I felt like I was rushing like crazy.

Here are my notes. I'd like to do a more in depth post on this some time with screenshots and descriptions and stuff, but until then here are the notes I promised:

//San Diego .NET User Group - Tools

//Why bother with tools?

{
-Outsource busywork (it really adds up)
-Minimize repetition - minimize stupid mistakes
-Keep your focus on what's important
-Windows and Visual Studio are NOT optimized for you...
}



//My Short List
{
ClipPath - Right-Click copy file path to clipboard
http://personal.vsnl.com/sureshms/utilities.html

Copy Path - A little better than ClipPath, but same idea
http://blogs.vertigosoftware.com/ralph/archive/2006/09/28/Copy_Path_Shell_Extension.aspx 
Cropper - Simple screen capture
http://blogs.geekdojo.net/brian/articles/Cropper.aspx

Notepad++ - A great Notepad replacement
http://notepad-plus.sourceforge.net/uk/site.htm

ClipX - Clipboard history
http://bluemars.org/clipx/

Paint.NET - Simple image editor
http://www.getpaint.net/index.html

Colibri - Launcher that learns
http://colibri.leetspeak.org/

TimeSnapper - A black box for your computer
http://timesnapper.com

Reflector - View source for .NET compiled code
http://www.aisto.com/roeder/dotnet

Regulazy
http://tools.osherove.com

WinMerge - A nice diff / merge tool
http://winmerge.sourceforge.net/

TortoiseSVN - Makes Subversion (SVN) easy
http://tortoisesvn.net/downloads
}

//Where to find more...
{
//Scott Hanselman's Developer Productivity Tools Screencasts
http://www.wrox.com/WileyCDA/Section/id-291881.html
http://www.hanselman.com/blog/ScottHanselmans2005UltimateDeveloperAndPowerUsersToolList.aspx

//My stuff
http://weblogs.asp.net/jgalloway
http://tools.veloc-it.com
}

[Tools] Switched to Notepad++, here's my C# syntax file

I replaced Notepad with Notepad2 on all my computers when Roy Osherove recommended it back in 2004. I've really appreciated it - it's small and lightweight like Notepad, but has some great features like syntax highlighting, block selection, and regular expression search.

A week ago, Jeff Atwood sent a funny e-mail about a Notepad2 dialog that annoyed him. It didn't bug me at all, but it got me curious about other notepad replacements. I took a look at Notepad++ and immediately made the switch.

Notepad++ (simple)

The main feature that drew me in was the multiple document (tabbed) interface - you can see in the shot above that I've got three documents open. Simple enough, but it really cuts down on the clutter. Once I started using Notepad++, though, it was the plugins that blew me away. The big plugin is TextFX (included, no separate install necessary), which turns this simple notepad into the Swiss Army Knife of text editors:

Notepad++

Now, don't go freaking out that this is too complicated - remember, this stuff's available in a menu if you want it, but if you want simple just look at the first screenshot and pretend I never showed you the second.

I wrote a quick Notepad++ autocomplete file for C# which includes most of the keywords, commands, and common namespaces.

Speaking at the 8/22 San Diego .NET User Group Meeting

The San Diego .NET User Group is having their second anual "toolbox" meeting on 8/22/06, and I'll be one of the presenters. This sounds like it will be a lot of fun - several user group members doing rapid-fire 15 minute presentations.

I'm really into coding productivity tools, so this is right up my alley. The hardest part will narrowing my tools list down to a 15 minute talk - my C:\Utils folder is 650MB, and I could easily run an all day class on programming utilities. I'm planning to post my notes after the talk.

Posted by Jon Galloway | with no comments
Filed under: ,

CodeProject - Avoiding software licensing makes for a very bad license

Update: CodeProject has added license support since I wrote this. Hooray!

Summary

If you're going to post code, take the time to post a license so others can use it. I'm talking about CodeProject here, but the same applies to other code sites as well as code you post on your blog.

The obligatory human interest back story

The first time I set up a project on SourceForge, I was frustrated with the requirement to choose a license. "I don't care about all this legal mumbo jumbo, I just want to share some code," I thought. Eventually I settled on an MIT license and got on with the real work (which, by the way, involved procedures that seemed way more complex and paranoid than the crypto procedures I had to follow when I was the communications officer on a billion dollar nuclear submarine).

Now I realize that choosing a license is one of the most important things you can do when you post code.

Here's a concrete example. Last week I felt like coding. I've been working on a business intelligence project that is extremely cool, but we're working in T-SQL, Analysis Services, and Reporting Services. No c# code for miles, at least yet. That's cool, but this kid's gotta write me some code from time to time or I start rewiring alarm clocks. So during work breaks and late at night, I worked on a few other small projects.

For the first application, I wrote up an animated GIF capture plugin for my favorite screen capture application, Cropper. I used NGif, a GIF manipulation library I found on CodeProject. I pretty much used it as a springboard, but I refactored the heck out of it. It turns out that the CodeProject code was pretty much a straight port from a Java GIF library, so it wasn't making any use of System.Drawing. It was also following a pretty ugly anti-pattern - "class variables good, parameters bad" - in which all methods take no parameters, manipulate class variables, and return void.

For the second application, I started messing around with FireEdit, an open source notepad replacement that runs on the DotNetFireball libraries. I made a small tweak - I saw that the Find / Replace didn't support regular expression searches, so I implemented it. It took a few hours at most, and probably 20 lines of code.

Now here's the point of all that. I submitted a patch for my FireEdit changes, but my NGif changes are in code limbo. CodeProject makes it extremely easy to post and article with some code, but it's pretty much designed to prevent any of that great code from going any further. I could argue my code is fair use and not infringing on the NGif copyright; I could also re-port from the public domain Java source. The point is I shouldn't have to think about that - the CodeProject the license should be more explicit.

Note that I'm not really all that concerned about this specific (NGif) case, I'm just using it as an example. For the sake of argument I'm assuming the worst case - that I never hear back from the author of the NGif article. That's obviously not a fair assumption in this specific case, but judging from the comments on the majority of CodeProject articles it's a far assumption in the general case.

There are two huge problems that constrain code posted on CodeProject: a restrictive default license, and lack of a migration path.

CodeProject has a very restrictive default license

The default CodeProject license is actually pretty restrictive. It's not even really an open source license (according to the generally accepted OSI definition), since it doesn't allow for free redistribution or derived works. The CodeProject usage terms are buried in an FAQ:

Can I use code snippets and programs in my own work?

You can use code snippets and source code downloads in your applications as long as

  • You keep all copyright notices in the code intact.
  • You do not sell or republish the code or it's associated article without the author's written agreement
  • You agree the code is provided as-is without any implied or express warranty.

Some authors may also have specific restrictions on using code in commercial apps such as providing credit in documentation or sending them an email first.

That's it. Unless the author has included license in a readme.txt, license.txt, or copyright message in the code comments, the code is publised under the same license as the article. The problem is with the second bullet point - you can't re-publish the code without the author's written agreement. That may sound pretty reasonable if you're thinking about these as articles, but it's terrible if you're thinking about the code.

Let's say I fix some bugs in some CodeProject code - the best I can do is post a comment. If the author doesn't reply back, my bug fixes will stay hidden in that comment forever. I'm not allowed to publish my fixes.

Contrast that with code on SourceForge. First of all, since they make you pick from one of several standard open source licenses, and the license is plainly displayed with the project details. Secondly, most open source licenses allow for derivative work, so if an author abandons code or isn't driving the project where users want it to go, the users can fork it.

CodeProject, as one of the leading code sites, needs to grow up and learn about licensing. It's likely that the lack of focus on licenses comes from a "we're all friends here, let's not get bogged down in that licensing stuff" attitude, but the reality is that if you want to let people use your code, you need to grant them permission. I'd vote for a default BSD license1 which can be overridden by the article author to one a small selection of OSI licenses.

CodeProject offers no migration path

Assume a CodeProject becomes popular. A number of developers start using it, and over time they start offering contributions - recommendations, bug fixes, etc. These projects have outgrown CodeProject's simple article format and need to move to a host that offers project hosting features like source control, bug tracking, and patch management. There are a number of CodeProject graduates who have gone on to sites like SourceForge, GotDotNet, CodePlex, and Google Code.

Here's the problem - CodeProject, one of the top Visual Studio and .NET development communities on the internet, is completely oblivious to project hosting sites. There have been success stories where dedicated and determined CodeProject authors have done the research and migrated their code to a project hosting site, but it's the exception to the rule. I understand that CodeProject's goal is simple articles rather than project hosting, but as a premier code destination site with 3.2 million members they should at least have some sort of migration path. The best would be some kind of migration wizard, and a site with this kind of volume could probably get some cooperation from project hosting sites who would gain from hosting the projects.

Scott Hanselman has referred to CodeProject as "the bathroom wall of code", but I think a better analogy is the code junkyard. People haul their code over, and other people pick through it looking for parts. It could be so much more...

Epilogue

While writing this article, I realized that I've been posting a lot of code snippets without any stated license for the past 3 years. I've added a notice stating that my content is published under a Creative Commons license, and any code is published under Public Domain license unless otherwise stated.

If you post code, have you posted a license?

For further reading:
Scott Hanselman - Open Source Versus Source Out In The Open
Phil Haack - Developer's Guide To Open Source Software Licensing

1The BSD license has been referred to as a "copy center" license, which is fitting. From the political point of view, it's between the "Mine mine mine all mine!" copyright and the "If you want to use our code you have to join our commune" copyleft GPL license. From a humorous point of view, it's copy center as in "Go to the copy center and make as many copies as you'd like!" Craig Andera summed the BSD license up well on his humorous FlexWiki License Research page: "Do what you will, but don't blame me. Also, do not try to use our name to make your crappy knock-off look legitimate."

UPDATE: I published my NGif modifications as part of the Cropper Plugins project on CodePlex. Let me know via comments if you think NGif should be spun off as a new library / project on CodePlex or somewhere else.

More Posts