Saturday, August 11, 2012

MSDataSetGenerator Gone Wild

As regular readers of my blog may know, I’m big into Typed DataSets (but not the TableAdapters that can sometimes get generated with them. See my blog posts about this topic, starting with this one: http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html).

Two months ago I ran into a problem when the MSDataSetGenerator went crazy. I asked questions about it on the Forums and ended up discovering a workaround for it myself. Then, earlier this week it happened again and I couldn’t remember what my workaround was!!  I looked for my post from 2 months ago on the Forums and my workaround saved the day. I figured it was time to write a blog post about it.

Here’s an excerpt from my original forum post about what was happening:

In the past, I've not had any problems generating a Typed DataSet from my .xsd. (I'm using VS 2010). The project is set to .NET 4, but the MSDataSetGenerator refuses to generate TypedTableBase in the  Designer.cs file (still using DataTable).  I've tried everything ... deleting the Designer.cs, right-clicking the .xsd in the solution and "Run Custom Tool", deleted MSDataSetGenerator from the CustomTool property and then adding it back in,  etc.etc.etc.   Nothing works, it keeps generating DataTables  instead of the proper TypedTableBase.

The weird thing is that, as far as I know, the only time it's supposed to generate DataTable is if your project targets .NET 3.0 or lower. .NET 3.5 and above should generate TypedTableBase. But that’s not what was happening. But I finally figured it out … here’s my “Eureka” post from the forum:

Holy cow! This is strange! I typically add a DataSet by doing the following:

  1. Copy an existing .xsd file to my project's folder.
  2. Right-click the project in Solution Explorer and "Add Existing", choosing the .xsd
  3. Add the MSDataSetGenerator to the Custom Tool property if necessary.
  4. Generate the Typed DataSet

... I've been doing it this way for years (but haven't always been paying attention to what gets generated, because I haven't typically used LINQ with the DataSets until recently).

Someone mentioned to me that I should try adding DataSets a different way. Instead of "Add Existing", I should "Add New Item" and choose a DataSet item. Then I can copy/paste the xml into it. I tried that in my current problem project and guess what ... it generated the TypedTableBase!  And, lo and behold, the DataSet that refused to generate TypedTableBase was now doing it correctly too!!  Weird!!

So, I decided to test it in a brand new project. I closed the solution (but did not close VS). Created a new solution/project, copied an .xsd file, "Add Existing", generate ... still TypedTableBase (I was expecting it to be DataTable, since I didn't "Add New Item", DataSet). Hmmm ... maybe it was because I didn't start with a fresh Visual Studio? I shut it down, started up VS again, went through the process a second time with a brand new solution and created the DataSet with "Add Existing" ... this time ... DataTable, as I now expected it to do.

And again, as soon as I did "Add New Item", DataSet ... both DataSets again generated TypedTableBase.

But wait ... there's more! As soon as I shut down Visual Studio and started it up again, the DataSets again revert to generating DataTables instead of TypedTableBase (until I "Add New Item", DataSet, then it's fine again).

Sounds like a major bug to me .... anyone else see this behavior?

UPDATE (two years later, 12/30/2014):
I have been meaning to update this blog post ever since a reader commented with a much better workaround to the bug. Not everyone reads comments, so this great idea may have been missed by some. Here is the comment, written by Anonymous:

If you open up Visual Studio (2008 in my case) and you have not yet opened any xsd dataset in a *graphical* designer, the custom tool will generate the designer code the *old* way (derived from a normal DataTable). After you open an xsd - any xsd - for the first time in a graphical designer, from that point forward the custom tool will generate the designer code the *new* way (derived from TypedTableBase).

Just remember to *not* make your updates in the graphical designer, just open it and then close it. And that only has to be done once (each time you open a new instance of Visual Studio).