Archive for the ‘i-think IT’ Category

VSMDI Normalizer

Thursday, February 11th, 2010

Have you noticed that your Visual Studio test lists always seem to get re-ordered? Make sense of this randomness with the VSMDI Normalizer.

It works by sorting your test lists and tests by name, creating a consistent ordering, allowing better merging and comparison of test lists. It’s a command line tool so it can integrate with automated processes really well.

It works in two modes:

  1. Target Mode: Specify the VSMDI file as the first argument and the target output file as the second. If the target exists it will be overwritten. This is ideal if not everyone is using VSMDI Normalizer. Some file comparison tools accept external converter tools (such as Beyond Compare).
  2. In Place Mode: The VSMDI file will be normalized in place. This would be a good operation to run prior to check in. Just specify the VSMDI file as the first and only argument at the command line.

Download VSMDI Normalizer Now (~13K)

For support, visit http://www.i-think22.net/support/

VSMDI Normalizer is free for personal and commercial use. It comes with no warranty, explicit or implicit.

To use VSMDI Normalizer with Beyond Compare:

  1. Open Beyond Compare
  2. Select Tools > File Formats
  3. Click New
  4. Enter *.vsmdi as the mask
  5. In the Conversion Tab, select “External program (Unicode filenames)”.
  6. Browse for the VSMDI Normalizer tool (for the Loading field).
  7. Append the following to the Loading path: ” %s %t” (without the quotes).
  8. Check Disable editing
  9. Click Save and Close

Windows Easy Transfer: Easy when you know how

Tuesday, October 6th, 2009

I recently installed Windows 7 RTM on my laptop. Knowing that Asus didn’t supply 64-bit drivers for my laptop I installed the 32-bit version. After all, I only had 2GiB of RAM anyway.

Working from home the last few weeks has put more stress on my laptop than it has previously and I was constantly hitting my 2GiB limit leaving my hard drive thrashing as Windows struggled to swap pages in and out of memory.

I was surprised when I installed Windows 7 that I didn’t need to download any drivers from my manufacturer (Asus). My graphics drivers were installed through Windows Update and everything else worked out of the box. ((Unfortunately this didn’t include my Bluetooth drivers, but as I am now using the Microsoft Explorer Mouse this doesn’t seem like such a loss.))

So, after some encouragement from a friend on twitter I decided to try installing the 64-bit version of Windows 7 and if it worked, move up to 4GiB of RAM.

I already had the 64-bit image ready to go on Windows Deployment Services, but I had just recently finished setting up my machine perfectly. I was particularly worried about having to reconfigure Outlook and set up new PST file. Now I could have tried copying my user profile and transferring that way, but instead I figured that I’d give Windows Easy Transfer a try. Once I passed the initial welcome screen I was confronted with the following options:

An Easy Transfer cable

I guess this is a good idea for people who don’t have a wired home network. I didn’t have one of these cables (and I don’t think looping it back to the same computer would work right) so I moved to the next option.

A network

Surely this was the option I wanted. After all, I wanted to copy the files to my network server. Unfortunately, no. This option migrates directly to the new computer. This wasn’t right either.

RemovableDiskTransfer

An external hard disk or USB flash drive? That sounds very specific. Fortunately this includes network drives too. In fact, it just brings up a standard file dialog so you could likely store the migration file anywhere you want.

Then it was just a case of following the on-screen directions. It not only backed up the Documents folder, but it grabbed other folders on the disk and on different partitions. Unfortunately it doesn’t grab the settings for all applications, but it covered enough for my needs.

Once you’ve migrated back you get this handy migration report which you can use as a guide to see what applications you still have to install:

Previously Installed Applications

LINQ to SQL and tables with no Primary Key

Friday, July 24th, 2009

I ran into an interesting issue with LINQ to SQL yesterday. I had to update a table with no Primary Key. As I expected, LINQ to SQL wasn’t too happy with this scenario. Unfortunately LINQ to SQL will only throw an exception when you try to Insert or Delete a record with no primary key. Updates fail silently.

It’s actually quite obvious when you look into what is happening. To do an update you would usually do something like this:

var update = (from v in db.SimpleRecords
              where v.identifier == 12
              select v).First();
update.value = "new value";
db.SubmitChanges();

Of course, nothing happens. Here’s the code (slightly edited for readability) that is generated by the LINQ to SQL classes:

[Table(Name="dbo.SimpleRecord")]
public partial class SimpleRecord
{
   private int _identifier;

   private string _value;

      public SimpleTable()
      {
      }

      [Column(Storage="_identifier", AutoSync=AutoSync.Always,
         DbType="Int NOT NULL IDENTITY", IsDbGenerated=true)]
      public int identifier
      {
         get
         {
            return this._identifier;
         }
         set
         {
            if (this._identifier != value)
            {
               this._identifier = value;
            }
         }
      }

      [Column(Storage="_value", DbType="VarChar(50)")]
      public string value
      {
         get
         {
            return this._value;
         }
         set
         {
            if (this._value != value)
            {
               this._value = value;
            }
         }
      }
}

Without a primary key the two following interfaces aren’t emitted: INotifyPropertyChanging and INotifyPropertyChanged

Therefore LINQ to SQL doesn’t know that your record has changed (so can’t warn you that it can’t update).

Now that you understand the problem the solution is simple: Define a primary key in your table.

LINQ Talk from Queensland MSDN User Group

Thursday, May 7th, 2009

Last month I did a talk on LINQ at the Queensland MSDN User Group. For your viewing pleasure the talk is available on Live Meeting. Check it out here:

LINQ: Powerful Stuff (QMSDNUG)

You may need to skip the first 5 minutes.

Slides are available here: http://linq.i-think22.net/LinqApril2009.pdf

Demos will be available soon.

Writing XML with XElement

Friday, February 27th, 2009

In my last post we looked at how you can use LINQ to XML and XElement to parse XML. But what if you want to create XML files programmatically? Or modify an existing XML document?

Let’s start by looking at how we might add a new entry to our blog. Here is the XML file again:

<?xml version="1.0" encoding="UTF-8"?>
<Blog>
   <Entries>
      <Entry Archived="false">
         <Title>My First Post</Title>
         <Body>I love LINQ. It's the best</Body>
         <Comments>
            <!-- TODO: Shouldn't comments have authors? -->
            <Comment>I love LINQ more</Comment>
            <Comment>LINQ is the way of the future.</Comment>
         </Comments>
      </Entry>
   </Entries>
</Blog>

So we want to add a new Entry under the Entries element. We’ll also assume that our XML file has been parsed into an XElement variable blog.

We’ll start by creating our entry first:

var entry = new XElement("Entry");
entry.SetAttributeValue("Archived", false);
entry.Add(new XElement("Title", "My Second Post"));
entry.Add(new XElement("Body", "Just a quick post."));
entry.Add(new XElement("Comments"));

We started by creating the element, set the “Archived” attribute, then added the other necessary elements. I’ve still added the Comments element even though it will be empty. Depending on the rules that have been set about how I should layout the XML it might be optional.

To check that my code worked I plugged it into LINQPad and dumped the value of entry like so:

entry.ToString().Dump();

The results showed me the following:

<Entry Archived="false">
   <Title>My Second Post</Title>
   <Body>Just a quick post.</Body>
   <Comments />
</Entry>

Wow, that’s exactly what we want. Even though we used a Boolean value instead of a String for the attribute, XElement was smart enough to display its value as a human readable string. The XML is also nicely formatted and readable. I added the call to ToString() to emphasise that it wasn’t LINQPad that was responsible for the improved formatting.

What we have done here is generate an XML fragment. Sometimes it is easier to think of large XML files as smaller fragments that can be handled independently.

So now all we have to do is find the Entries element and add our entry XElement to it like so.

blog.Element("Entries").Add(entry);

This will leave us with the final XML looking like this:

<Blog>
   <Entries>
     <Entry Archived="false">
       <Title>My First Post</Title>
       <Body>I love LINQ. It's the best</Body>
       <Comments>
         <!-- TODO: Shouldn't comments have authors? -->
         <Comment>I love LINQ more</Comment>
         <Comment>LINQ is the way of the future.</Comment>
       </Comments>
     </Entry>
     <Entry Archived="false">
       <Title>My Second Post</Title>
       <Body>Just a quick post.</Body>
       <Comments />
     </Entry>
   </Entries>
</Blog>

What about our XML declaration?

You might be wondering why the ToString() method of XElement doesn’t include the XML declaration. Because XElement represents a fragment of XML which could appear anywhere in an XML document. If it included the XML declaration it would lose this flexibility. However there is a workaround if you are outputting to a final file.

var blogDump = new StringBuilder();
blog.Save(new StringWriter(blogDump));

The Save() method on XElement automatically adds an appropriate XML declaration, which is probably a good idea as it sorts out the complicated things like the encoding and XML version (which I’ve never seen as anything other than 1.0 to date). The Save() method can take either the name of a file (as a String), an XmlWriter or TextWriter. In the example above I’ve used a StringWriter (which is a subclass of TextWriter) to save XML to a StringBuilder object which I could then use to build a string containing the XML. Save() also takes a second parameter, SaveOptions which allows you to save your XML file without the extra whitespace that I’ve shown above. If you want to save those bytes it might be worth looking at this option.

Where do we go from here?

I haven’t yet decided what my next LINQ post will cover (although LINQ to Entities is high on the agenda), so I won’t promise anything here now. I have much more to say still about LINQ, so feel free to post in the comments suggestions for areas to cover in future posts and the areas you would like to see covered in more detail. So far this has been fairly introductory and we’ll be building towards more advanced topics over the coming weeks.