Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

March 2005 - Posts

Using CommandBuilder to create dynamic command objects

At the moment, I'm working on a conversion between 2 databases. I was looking for a way of avoiding the tedious job of creating command objects for each of the tables I needed to insert data into. In most projects I worked on over the last couple of years, I was able to use code generation to do this. But not in this project. And I did not have the time to write new templates, or evaluate existing ones.

So I went back to another option which I used before I had access to code generation, the CommandBuilder object. The following example shows you how this works on the Customers table in the Northwind database:

   SqlConnection dcNorthwind = new SqlConnection();

   SqlDataAdapter daCustomers = new SqlDataAdapter("Select * From Customers". dcNorthwind);

 

   SqlCommandBuilder cb = new SqlCommandBuilder(daCustomers);

 

   SqlCommand cmdInsert = cb.GetInsertCommand();

   SqlCommand cmdDelete = cb.GetDeleteCommand();

   SqlCommand cmdUpdate = cb.GetUpdateCommand();

The CommandBuilder object builds the commands for insert, update and delete using the results of the SQL query. Using this I created the following generic method to create the command objects I needed:

public static void BuildCommandObjects(string conString, string tableName,
         ref SqlCommand insertCmd, ref SqlCommand updateCmd, ref SqlCommand deleteCmd)
{
   if ((conString == null) || (conString.Trim().Length == 0)) throw new ArgumentNullException( "conString" );
   if ((tableName == null) || (tableName.Length == 0)) throw new ArgumentNullException( "tableName" );

   try
   {
      using (SqlConnection sqlConnection = new SqlConnection(conString))
      {
         using (SqlDataAdapter dataAdapter = new SqlDataAdapter("Select * from " + tableName, sqlConnection))
         {
            using (SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(dataAdapter))
            {
               insertCmd = cmdBuilder.GetInsertCommand();
               updateCmd = cmdBuilder.GetUpdateCommand();
               deleteCmd = cmdBuilder.GetDeleteCommand();
           
}
         }
      
}
   }

   catch (SqlException ex)
  
{
     
throw new MyException(string.Format("Building command objects for table {0} failed", tableName), ex);
   }
}

The  SqlCommand objects created by this procedure can be used in the UpdateDataSet procedure from the Microsoft.ApplicationBlock.Data.SqlHelper class. Creating objects in this manner comes at a price, as usual. And that price is database performance. Another issue is that when you have an auto-identify column as your primary key, the value is not return by the insert command. More details on performance problems and limitations can be found in this MSDN article. However, for the project I work on now, these limitations are not really a problem.

And then there is a big advantage as well:

The command object is truly dynamic. A change in your table automatically changes the insert, update and delete commands. So no need to change your code, or re-generate it.

Using the CommandBuilder object was ideal for my application. I could write the code to convert data from one table to another, without worrying about the insert statements for the target tables. I did not need to re-write some of the code after the table was changed. And those changes include type and size changes for some of the columns. However, if wether you should use CommandBuilder or code-generation really depends on your project.

Regular expressions library

For the project I work on now, I needed to know if the string contained a valid dutch postcode value. Best way to do this is using a regular expression. For example:

int IsPostcode(string value)
{
   Regex regex =
new Regex(@"^[1-9][0-9]{3}\s?[a-zA-Z]{2}$");
  
Match m = regex.Match(value);
  
return m.Success;
}

The problem is of course finding the right expressions. For this, I now use Regular Expression Library on the internet. Most of you probably already know this web site. For those who don't, check it out. It's a really good resource for regular expression.

Visual Studio 2005 Express series

Someone might have blogged this, and for us professional developers it might not even be such a issue. But I found the Express products for Visual Studio at Microsofts corporate website.

“The Express products, expanding the Visual Studio product line to include lightweight, easy-to-use, easy-to-learn tools for hobbyists, enthousiasts, and novices who want to build dynamic Windows applications and Web sites.“

As I said, for professional developers these downsized versions might not be interesting. But if you hate running the full version at home, it will provide you with a good alternative. And since they are available for download now, you have the opportunity to start looking at the new versions of these development tools. The beta's include the following versions:

Posted: Mar 24 2005, 09:30 AM by Jan Schreuder
Filed under:
Powertoys weblog

I've visited the PowerToys weblog on several occasions. It is good source for VS.Net add-ins and stuff. Today I found two interesting items there which I just had to share with you:

  1. For all you VB.Net lovers out there, a new version of VBCommenter has been released. It gives you, as a VB.Net developer, the same XML commenting capabilities that we C# developers simply adore :-)
  2. An VS.Net add-in for the CodeHound web site. CodeHound is a search engine which you can use to find code samples on the internet. Using the add-in, you can quickly search for code samples. Only problem is that codehound is a little slow. Advantage is that you only get .Net resources.

So have a peek at PowerToys weblog.

Update: You gotta be patient when you use CodeHound. It works, but's it's a bit slow...

Posted: Mar 23 2005, 03:28 PM by Jan Schreuder | with no comments
Filed under:
Microsoft Anti-Spyware

On December 16, 2004, Microsoft aquired Giant Company Software Inc. Giant sold and maintained an anti-spyware application. A few weeks later, Microsoft released a beta version of their new anti-spyware application. 

I've been running it both at home and at the office since then, and I'm really enthousiastic about this product. Once installed, the application can be configured to automatically detect the installation of spyware. On my home systems, it found spyware that AdAware left untouched. So I'm convinced. Especially now that I've read that Microsoft is considering to ship the tool as part of Internet Explorer 7.

More information on this tool can be found here: Microsoft Windows Antispyware. If you want to download the beta, click here.

Posted: Mar 17 2005, 01:05 PM by Jan Schreuder | with no comments
Filed under: ,
DataSet Quick watch

I know a lot of people use the DataSet QuickWatch utiltity developed by Mohammed Barqawi. The first version of this was posted May 2004.

Matt Simner implemented a few additional features which are very interesting, such as:

  • Typed DataSet support.
  • Support for DataTable and DataRow
  • Row Filter option
  • Visual changes.

Those interested can find the full article here. From here, you can also download the code.

Posted: Mar 16 2005, 02:33 PM by Jan Schreuder | with 3 comment(s)
Filed under:
Code inspections. What do you think?

In one of my previous posts I tried to make a case for code inspections. I personally believe that regular code inspections, provided they are conducted correctly, can greatly improve the quality of your code and thus the quality of your end product.

The post contained an example to prove my point. The wrong example as it turned out, since the code that was delivered after the inspection contained a new error. However, three developers actually saw that and pointed them out to me. So to me, another example that code inspections can work. However, one of the commentors (Dennis van der Stelt) argued that this proved that code inspections did not work! One comment even said that he'd never seen documentation on the subject or large companies using this method.

Therefore some resources on code inspections:

  • Michael E. Fagan worked at IBM and formalised and introduced code inspections back in 1976. His website, as well as electronic versions of his books can be found at www.mfagan.com. Check out the resources section. IBM still promotes code reviews, for example in Java development.
  • GoldPractices.Com has a section on code inspections. You can find a full description of the code inspection process here.
  • Another interesting read is “Software inspections are not for quality, but for engineering economics“, by Tom Gilb. Tom Gilb teaches code inspection methods and is considered an authority on code inspections. Some of the companies he works for: Nokia, Intel, Microsoft, Sun Microsystems. The document argues that “Inspection should be used as a specification Quality control tool. The 'quality being checked' is the specification consistency with your best practice standards.

So let's start a nice discussion here and let me know your opinion on code inspections. Do you think code inspections can help improve the quality of software, or do you think it's utterly useless? Or maybe you have experience with code inspections?

How to write unmaintainable code
I was looking for resources on code inspections for my next posts on that subject and bumped into this: How to write unmaintainable code. This is just really funny, even if it was found on a Java releted site. Just had to post it here :-)
Making a case for code inspections

Last week, I was asked to look at a problem in our companies application framework. It appeared that our database component sometimes failed when using transactions. While looking at that problem, I also saw some other regularities that, in most cases, might not cause a problem. But looking at the code, one could easily see that something was wrong.

Take for example this piece of code which I've editted for the purpose of this article. Oh, and if you recognise this code as being yours, don't be offended. We all make mistakes like this one.

private IDataReader ExecuteReader(IDbConnection connection, IDbTransaction transaction, 
   CommandType commandType, 
string
commandText, IDataParameter[] commandParameters)
{    
   IDataReader   dataReader = null
;
   bool          mustCloseConnection = false
;
  
// Create a command and prepare it for execution
   IDbCommand    cmd = connection.CreateCommand();

  
try
   {
     
// Prepare command opens the connection when it is closed and set the boolean
     
// mustCloseConnection to true
      PrepareCommand(cmd, connection, transaction, commandType, commandText, 
         commandParameters,
out
mustCloseConnection);

      dataReader = cmd.ExecuteReader();
      cmd.Parameters.Clear();
      return
dataReader;
   }
   catch
(Exception ex)
   {
      if
(mustCloseConnection) connection.Close();
      throw
ex;
   }
}

At a first glance, this appears to be just fine. And the NUnit test for this method 'proved' that the method worked correctly. But when you look more closely, you will notice that the database connection never get's closed when the PrepareCommand method opens the connection. I fixed this problem simply by moving the line 'if (mustCloseConnection) connection.Close();' to a new finally section.

And this is where I want to make my case for regular code inspections. It is very likely that this problem would have emerged during such an inspection. We also know that fixing a problem before a product is released to the end-user will be cheaper than fixing it after that stage. My next post will be about code inspections and how they can be organised, so stay tuned!

If you have thoughts and/or oppinions about, feel free to post comments!

And for all you code addicts, here's the method as I've changed it:

private IDataReader ExecuteReader(IDbConnection connection, IDbTransaction transaction,
        CommandType commandType, string
commandText, IDataParameter[] commandParameters)
{
   IDataReader dataReader          = null
;
   bool        mustCloseConnection = false
;

   try
  
{
     
// Create a command and prepare it for execution
     
IDbCommand cmd = connection.CreateCommand();
     
// Prepare command opens the connection when it is closed and set the boolean
     
// mustCloseConnection to true
     
PrepareCommand(cmd, connection, transaction, commandType, commandText,
            commandParameters, out
mustCloseConnection);

      dataReader = cmd.ExecuteReader();
      cmd.Parameters.Clear();
   }
   catch
(Exception ex)
   {
      // The connection must be closed here when the boolean is true. Because
      // when you close it in the finally section, the reader gets closed too!

      if (mustCloseConnection) connection.Close();
      throw
ex;
   }
   return dataReader;
}

I closed the comments on this item, but I've included the original text of the comments posted so far below!

# re: Making a case for code inspections 3/15/2005 2:26 PM Dennis v/d Stelt

I highly doubt this would've been caught in a code review. Perhaps when you're doing pair programming, but not when you're just looking at the code.

And you might want to make sure you're not creating unnecessary transactions or add a lot of reads to your transaction. Transactions can/will lock your table/rows when reading, until the transactions commits or rolls back.

And reading is what you're doing here.

# re: Making a case for code inspections 3/15/2005 3:00 PM Jan Schreuder

If this was not found in a code review, then the review was not done properly. Code review is not 'looking at the code', it is inspecting the code to see if it is functionally and technically correct.

I will agree that not all errors will be found in a code review. That is not what a code review is intended to do, because it is nearly impossible to do so.

The point I was trying to make was that code inspections could have trapped this problem. Even if you only find 50% of these problems, you cannot deny the fact that if you can find and solve 50% of these problems before they reach the end-user, your overall product quality has improved.

# re: Making a case for code inspections 3/15/2005 9:12 PM Roland

You close the connection before using the returned IDataReader? Are you serious?

# re: Making a case for code inspections 3/16/2005 12:12 AM Erwyn van der Meer

It seems indeed your change is wrong. I agree with Roland you should not close your connection when returning the IDataReader (so in the case when no exceptions occur) because this closes the IDataReader. Remember code in the finally block runs in all cases. So the connection should only be closed when an exception occurs, as in the original code.

But I spot another problem. In general, catching Exception is bad practice. Rethrowing it with "throw ex;" even more so. That way you loose the call stack information up to that point. If you must rethrow, do it without specifying the Exception object. Just say "throw;". That way the call stack in the Exception object is not reinitialized.

In general "catch (Exception ex)" is considered bad practice because do you really know how to handle an OutOfMemoryException or an ExecutionEngineException gracefully? When these exceptions occur no code can reliaby run anymore.

In this case catching the base class Exception might be justified because you really want to try to close the connection.

But you really should enclose the "connection.Close();" in another try block and ignore any further exceptions with an empty catch block, because this statement might throw another exception. If "connection.Close();" throws, you loose your original Exception object. According to the MSDN docs the Close method for SqlConnection method throws a SqlException when the connection could not be opened.

# re: Making a case for code inspections 3/16/2005 8:10 AM Jan Schreuder

You're right, closing the connection closes the reader. So I introduced a bad fix here. I was mislead by the NUnit tests for this procedure which, as I found out this morning, always opened the connection before calling the procedure. So I did a rollback for that change.

# re: Making a case for code inspections 3/16/2005 8:19 AM Dennis v/d Stelt

Another proof that what you want to achieve with code reviews doesn't work. Many developers have looked at the code and Roland is the first to notice that you broke the code!

# re: Making a case for code inspections 3/16/2005 8:21 AM Jan Schreuder

No Dennis, this is actually the proof that code reviews work. You've now looked at the code and found a problem. So did Roland and Erwyn!

Yes, I introduced a new problem in the code. If someone had reviewed my work, this would never have happened.

# re: Making a case for code inspections 3/16/2005 8:30 AM Dennis v/d Stelt

Come on Jan, give up! :)

I've never read any document or seen any company where code reviews are done by 10 people or more!

I see this:
- One guy (or girl) creates the method
- Jan reviews it, brakes code

Code is in producten, áfter code review

# re: Making a case for code inspections 3/16/2005 8:39 AM Jan Schreuder

I've closed the comments on this item. But you can still express your views on code inspections in another item.

I'm not giving up, Dennis.