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).



12 comments:

  1. Brilliant, Sis!! I love your blog. No, seriously!! Excellent. I don't understand a thing, but it's pretty impressive!

    ReplyDelete
  2. Hahaha ... thanks Shaz!
    You're worse than I am when it comes to blog posts. The last post on your blog was 5 months ago! At least mine was only 4 months ago. ;0)

    ReplyDelete
  3. Thx for knowing that my last blog post was 5 months ago! I know! Terrible. I need to get out - walking, kayaking, biking, etc. - so I can get some inspiration!

    ReplyDelete
  4. Can you ask MS for a fix? I'm seeing similar misbehavior and no KB articles.

    ReplyDelete
    Replies
    1. Hmmm ... well, I can try, but I'm betting it's a lost cause. Even if they "take it under advisement", I bet it won't be high on the priority list, as they don't really promote Typed DataSets much anymore. I'll see what I can do though ....

      Delete
  5. One more note, you forgot to mention the place that the System.Data.DataSetExtensions reference factors into the generation of code...

    Beyond that, if I open the xsd in the graphical designer first, close it, and run the custom tool generator, I get the results I would expect (using TypedTableBase). If I don't first open the xsd in the graphical designer, it is hit-and-miss.

    ReplyDelete
    Replies
    1. I never open the .xsd in the graphical designer because of the issues with the TableAdapter, which I never use ... I have posts about that problem here also. Did you see them?

      And, what about the DataSetExtensions reference? I'm not sure what you're getting at with your mention of it.

      Delete
    2. I guess it is probably self-evident, but the System.Data.DataSetExtensions assembly reference seems to be where TypedTableBase<> comes from. If you target .Net 2.0 you will not be able to reference System.Data.DataSetExtensions and nor will the custom tool generator create TypedTableBase-derived tables either.


      As far normal .Net 3.5 and beyond projects go (that properly reference System.Data.DataSetExtensions) this is what I've found. It is a doozy, but you started this thing so you probably won't be surprised...

      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).

      Frustrating. No bug fix. No KB.

      Delete
    3. Oh, you are brilliant! As I said, I have always avoided opening my xsd in the graphical designer, I only open it and make any changes to it with the XML editor. The problems with the graphical designer only surface if you *make your changes* in the designer, but I tended to avoid it entirely. Less likely to inadvertently have the all that excess stuff get automatically put into my xsd.

      However, your suggestion that merely opening the xsd in the designer causes the correct TypedTableBase to be generated, peaked my curiousity (mainly because my workaround, detailed above in my post, basically sucks if you're using Source Control and have to check out the project just for adding and then deleting a bogus DataSet).

      So, anyway, I tried it. First, to make sure that it was going to generate incorrectly, I made a change to my xsd in the XML editor, saved it, then looked at the generated stuff. Sure enough, it generated DataTables. OK, then I opened the xsd in the graphical designer (but made no changes! only opened it!), closed the designer, opened the xsd in the XML editor, then made the change, saved it and looked at the generated stuff. Voila! It generated TypedTableBase!

      I like your workaround so much better than mine!! I'm going to do an update to this blog post later today (and also update that forum post with this new workaround).

      Thanks for your contribution! I guess you can teach an old dog (me) new tricks! ;0)

      Delete
  6. I have read this post with interest because these many years later, there is another, apparently unreported, bug in MSDataSetGenerator. I hadn't used the fool things for a long time, but am working for a company which is stuck in the past and uses only datasets for data access. Needless to say, I'm running into problems.

    I haven't encountered the problem specifically written about in your blog post, but I feel it is closely related.

    The scenario: I use a tool written by someone here which generates .xsd files for each table in the database. I plop that .xsd into my project folder structure and, in VS, right-click it and "Include in Project". It comes in fine, but there is a problem.

    One or more public properties are renamed. For reasons I cannot imagine, MSDataSetGenerator prefixes them with an underscore.

    If I open the thing in the graphical designer, the property name(s) appear normal. On a whim, I changed the property name in the property grid to something else, saved and rebuilt, then set it back to its original name, saved and rebuilt.

    This sometimes fixes the regenage underscore prefix, but it adds to my troubles; the datatable in this dataset is now prefixed with an underscore.

    From here it is irretrievably broken. I can only delete the file and copy another in its place, and include in project.

    Adding a new dataset to the project, and pasting my xml into it results in the same corrupted properties.

    The xml generated by the custom tool creates one dataset per db table, with one datatable within. The datatable is given the same name as the dataset which contains it. This may be part of the problem; I am currently testing.

    I considered that the property name violates some Microsoft reserved word, but cannot find documentation which declares this particular property name as a problem. In this case, the property is named "REGION".

    ReplyDelete
  7. It appears that MSDataSetGenerator doesn't like the word "region" used as a property name. I created a separate test table which included a property named "Region", then generated its xml. Bringing it into VS results in the Region property being prefixed with an underscore.

    Hopefully others may benefit from this. Also, I somehow misspelled renegade. above :D

    ReplyDelete
    Replies
    1. Sorry for not replying sooner ... I was in a meeting.

      Yeah, those reserved words do tend to bite you sometimes ... which I would have said if I wasn't in a meeting. =D

      As for your misspelling of renegade ... believe it or not, I actually did figure out what word you were trying to use. =D

      Delete