<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33753991</id><updated>2012-01-28T15:35:45.809-08:00</updated><title type='text'>Geek Goddess</title><subtitle type='html'>Musings from a Geek Goddess.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33753991.post-9212419181813091970</id><published>2011-11-23T08:54:00.001-08:00</published><updated>2011-11-23T08:54:55.617-08:00</updated><title type='text'>NAS Gone Bad</title><content type='html'>&lt;p&gt;Today’s post is not about my usual topic (.NET programming), but about the solution I used when my NAS (Network Attached Storage) went bad. It was a Western Digital My Book World Edition with a 1 TB Caviar Green SATA WD10EADS 5-1/4 inch drive (the one with the white light). The thing is, I was pretty sure my drive (and therefore my data!) was just fine. It’s just that the enclosure and all the electronics that make it “network attachable” was the part that went south. Or so I hoped.&lt;/p&gt;  &lt;p&gt;I took it apart (did I mention that I *hate* doing hardware stuff!!) and got the drive out. I thought I bookmarked a link to a video showing how to take it apart, but I guess I didn’t bookmark it and I can’t find the same video at the moment. Google for it though, you’ll find some “how-to” for taking the drive out of the enclosure. If you’re a whiz at hardware, you probably don’t even need a how-to video. It’s not rocket-science … even I could do it! ;0)&lt;/p&gt;  &lt;p&gt;Then I hooked it up to a SATA-to-USB converter and plugged the USB into my laptop. At this point, Windows Explorer would not assign a drive letter, but I could see the drive with the Disk Management utility. It was listed as having a Healthy but Unknown partition.&lt;/p&gt;  &lt;p&gt;After a little more Googling, I discovered that the drives that get put into these NAS devices are just about always formatted to some kind of Linux format … not readable by Windows!! &lt;strong&gt;Grrrr&lt;/strong&gt; …. now I have a lot more Googling to do!&lt;/p&gt;  &lt;p&gt;I found lots of discussions on the topic … apparently some of these NAS devices (not just Western Digital) give up the ghost on a regular basis! You can buy NAS devices that are disk-less … in other words, they’re just the enclosure with all the electronics for making it network attachable and you supply your own drive (I assume an unformatted drive). Which means that if Western Digital sold the same enclosure disk-less for this particular model, then I could just buy the enclosure, pop in my drive and be back in business!!!&amp;#160;&amp;#160; Unfortunately, I couldn’t find one and I suspect that they don’t exist for my model. &lt;strong&gt;Grrrr&lt;/strong&gt; …. back to the drawing board!&lt;/p&gt;  &lt;p&gt;I found a ton of links talking about how to create a Linux boot disk and boot your machine to Linux and enter in a whole bunch of gibberish Linux commands and it may (or may not) do the trick. There were like 20 steps in some of these how-to discussions! And I know absolutely nothing about Linux. I really did &lt;strong&gt;&lt;u&gt;not&lt;/u&gt;&lt;/strong&gt; want to mess with this! So, I kept looking …&lt;/p&gt;  &lt;p&gt;Then I found a nifty little driver that could allow a Windows machine to be able to read a Linux formatted drive! Because it’s a driver, it would work seamlessly with Windows. This was just what I was looking for! And it’s free! I downloaded it (&lt;a href="http://www.fs-driver.org/" target="_blank"&gt;Ext2 Driver for Windows&lt;/a&gt;). It will work for both Ext2 and Ext3 formatted drives. It installed just fine on my computer. Unfortunately, it didn’t do the trick … why? Because my drive wasn’t formatted with Ext2 or 3!!&amp;#160; More Googling showed me that it was probably an XFS formatted drive. &lt;strong&gt;Arrggghhh&lt;/strong&gt;!!! Will it never end?!?!?!&lt;/p&gt;  &lt;p&gt;One more round of Googling and I finally found a solution! It wasn’t free, but it was only about $30. I could live with that &lt;strong&gt;&lt;u&gt;if&lt;/u&gt;&lt;/strong&gt; it worked (&lt;a href="http://www.ufsexplorer.com/download_std.php" target="_blank"&gt;UFS Explorer&lt;/a&gt;). It’s a utility that can read all kinds of partition formats and there was a free trial download (limited to copying files smaller than 64KB) … so I downloaded it to take it for a testdrive. If it worked, I would buy it. You can only read/copy from the drive …&amp;#160; you can’t write to it. But I intended to copy all the files off of the drive, then reformat it to NTFS and install it directly on my machine (yuck … more hardware stuff). Luckily I already had a 2 TB USB drive and I had plenty of room on that drive. The trial showed that it copied the small files flawlessly, so I plunked down the $30 and bought it. It also worked flawlessly, copying every single one of my files off of the XFS partition!&amp;#160; &lt;strong&gt;Wow! Disaster averted!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now, all that’s left to do is reformat the 1 TB and stick it in my machine. But, since that’s hardware stuff, I’ll procrastinate on that task just a little bit longer.&amp;#160; =0)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-9212419181813091970?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/9212419181813091970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/11/nas-gone-bad.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/9212419181813091970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/9212419181813091970'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/11/nas-gone-bad.html' title='NAS Gone Bad'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-5114839529755255063</id><published>2011-10-08T17:09:00.001-07:00</published><updated>2011-10-08T17:09:57.904-07:00</updated><title type='text'>XmlSerializer and Implemented Interfaces</title><content type='html'>&lt;p&gt;Here’s the scenario: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Get some data from calls to a third-party API. &lt;/li&gt;    &lt;li&gt;Serialize that data to XML. &lt;/li&gt;    &lt;li&gt;Use XSLT to Transform that XML into a common set of classes. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The API utilizes Interfaces for all the objects it returns and it would have been nice if I could have simply used either XmlSerializer or DataContractSerializer on the objects I received, but of course nothing is simple. Suffice it to say that it doesn’t work, for either serializer.&lt;/p&gt;  &lt;p&gt;So, I’ve spent the last day or two working on implementing my own classes from the various third-party Interfaces for the objects I need. Basically, I’ll be using the API to get some data. Then I’ll have to copy the data into my own classes and then serialize it to XML.&lt;/p&gt;  &lt;p&gt;Theoretically, creating classes that implement on Interface should be easy (simply right-click on the Interface and choose “Implement Interface”. But, nooooo … even though I’m using Visual Studio 2010, it still generates properties the same way it did before the “invention” of automatic properties. In other words, instead of generating a property like this:&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;   &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;     &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;       &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public int &lt;/span&gt;VehicleID { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The property gets generated like this:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public int &lt;/span&gt;VehicleID
{
    &lt;span style="color: blue"&gt;get
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();
    }
    &lt;span style="color: blue"&gt;set
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotImplementedException&lt;/span&gt;();
    }
}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;When you’re talking about implementing a ton of properties, you don’t want to have to fix each of these manually. I knew I could find a way to generate these Interface properties differently, but I had forgotten all about code snippets. Had the old “slap on the forehead” moment when I read this blog post, written by Daniel Cazzulino, about how to do this:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://blogs.clariusconsulting.net/kzu/how-to-replace-default-interface-property-implementation-expansion-with-automatic-properties/" href="http://blogs.clariusconsulting.net/kzu/how-to-replace-default-interface-property-implementation-expansion-with-automatic-properties/"&gt;http://blogs.clariusconsulting.net/kzu/how-to-replace-default-interface-property-implementation-expansion-with-automatic-properties/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Duh! Why hadn’t I remembered how to do that myself? Gettin’ old I guess. =0(&lt;/p&gt;

&lt;p&gt;But wait, there’s more. Some of these Interface properties did NOT have setters and so they get generated with only the get. While this doesn’t cause a problem with DataContractSerializer, the XmlSerializer will not work unless you have both getters and setters. Daniel mentions, in an update at the end of his blog post, how to take care of this, by producing private setters for the generated property:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public int &lt;/span&gt;IncidentID { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private set&lt;/span&gt;; }&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately, because I’m copying data to my own classes, my class needs to have a public setter. In my case, this doesn’t really matter as far as the functionality of these classes, because I’m only using them so I can serialize the data to XML, so I don’t care that the “set” is exposed publicly.&lt;/p&gt;

&lt;p&gt;The two serializers produce very different XML. The task I will tackle next week is to see if that matters when I use that XML for my XSLT Transformations. For those interested, I’ll probably post the results of what happens with that little experiment next week. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-5114839529755255063?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/5114839529755255063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/10/xmlserializer-and-implemented.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5114839529755255063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5114839529755255063'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/10/xmlserializer-and-implemented.html' title='XmlSerializer and Implemented Interfaces'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7219327261411503186</id><published>2011-09-30T21:39:00.001-07:00</published><updated>2011-09-30T21:39:19.761-07:00</updated><title type='text'>DISTINCT - LINQ versus DataSet</title><content type='html'>&lt;p&gt;Wow, it’s been way too long since the last time I wrote a blog post. I’ve been busy, but that’s really no excuse. In my last post in April, I wrote about using &lt;a href="http://geek-goddess-bonnie.blogspot.com/2011/04/linq-with-datasets.html" target="_blank"&gt;LINQ with Typed DataSets&lt;/a&gt;. I did some benchmark comparisons with Selects and LINQ was considerably faster. Today I’m going to compare the DISTINCT capabilities of LINQ versus DataSets. &lt;/p&gt;  &lt;p&gt;As before, I’m using the same set of data … a DataTable containing 270,000 rows. I’ve filled the DataTable such that there’s a random number of duplicates in the rows, but it seems that the DISTINCT values always fall between 4750 and 4800 rows.&lt;/p&gt;  &lt;p&gt;There are some interesting results. When selecting DISTINCT values, over all columns in the DataTable, it definitely is best to use the old DataSet methods rather than LINQ. And, also surprising, is that the old-style 2.0 Typed DataSets (and likewise, plain old vanilla DataSets, not Typed) are actually faster than newer 3.5 Typed DataSets (refer to my last post, linked to above, that explains what is the difference between the two).&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:9fbaf271" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;   &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;     &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;       &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// ds20 is a 2.0 Typed DataSet (a regular DataTable)
// ds35 is the 3.5 Typed DataSet (a TypedTableBase) 
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt20 = ds20.Personnel.DefaultView.ToTable(&lt;span style="color: blue"&gt;true&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt35 = ds35.Personnel.DefaultView.ToTable(&lt;span style="color: blue"&gt;true&lt;/span&gt;);

&lt;span style="color: green"&gt;// Note that if you MUST use the DataRowComparer.
// If you don't you get all rows returned ... it won't find the duplicates.
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq20 = ds20.Personnel.AsEnumerable()
    .Select(row =&amp;gt; row).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default)
    .CopyToDataTable();

&lt;span style="color: green"&gt;// note that the only difference in syntax between
// 2.0 and 3.5 is that you don't use .AsEnumerable()
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq35 = ds35.Personnel
    .Select(row =&amp;gt; row).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default)
    .CopyToDataTable();&lt;/pre&gt;
      &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Benchmarking results show that the &lt;strong&gt;DefaultView.ToTable() is 7 times faster&lt;/strong&gt; than LINQ for &lt;strong&gt;ds20&lt;/strong&gt; &lt;strong&gt;(and 8.5 times faster&lt;/strong&gt; for &lt;strong&gt;ds35)&lt;/strong&gt;. The DefaultView.ToTable() is only slightly faster for ds20 than ds35 ( not significantly though) and with LINQ, ds20 is about 1.5 times faster than ds35. Most peculiar!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ToTable (ds20):&amp;#160;&amp;#160;&amp;#160; 77,937,500 ticks &lt;/li&gt;

  &lt;li&gt;ToTable (ds35):&amp;#160;&amp;#160;&amp;#160; 90,718,750 ticks &lt;/li&gt;

  &lt;li&gt;LINQ (ds20):&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 554,656,250 ticks &lt;/li&gt;

  &lt;li&gt;LINQ (ds35):&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 781,218,750 ticks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, there’s where the superiority of the DefaultView.ToTable() ends. Once you start looking for specific columns to be distinct, LINQ is faster. Let’s look at the one column scenario: First, the DataSet code (since all code for the DataSet methods are exactly the same for ds20 as for ds35, I’ll only show one):&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:9fbaf271" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt20 = ds20.Personnel.DefaultView.ToTable(&lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
      &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Pretty straightforward … nothing fancy. The benchmark times for both ds20 and ds35 are almost identical.&lt;/p&gt;

&lt;p&gt;But now, the LINQ gets trickier. Unfortunately, you’ve got to create the resulting DataTable (including the column) before you can “fill” it from the LINQ query. If there’s a workaround for this, I sure haven’t found it. Here are the two LINQ queries:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:9fbaf271" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// note that you have to create the DataTable first, 
// AND add the column!
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt;();
dt.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq20 = ds20.Personnel.AsEnumerable()
    .Select(row =&amp;gt;
    {
        &lt;span style="color: #2b91af"&gt;DataRow &lt;/span&gt;newRow = dt.NewRow();
        newRow[&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;] = row.Field&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;newRow;
    })
    .Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default).CopyToDataTable();

&lt;span style="color: green"&gt;// note that there are 3 differences in syntax for ds20 &amp;amp; ds35:
// 1) as before, you don't use .AsEnumerable()
// 2) you must check for null
// 3) you can use the typed column syntax (row.firstname)
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt;();
dt.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq35 = ds35.Personnel
    .Select(row =&amp;gt;
    {
        &lt;span style="color: #2b91af"&gt;DataRow &lt;/span&gt;newRow = dt.NewRow();
        newRow[&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;] = row.IsfirstnameNull() ? &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot; &lt;/span&gt;: row.firstname;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;newRow;
    }).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default).CopyToDataTable();&lt;/pre&gt;
      &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now for the benchmark numbers.&amp;#160; &lt;strong&gt;LINQ is more than 5 times faster&lt;/strong&gt; than the DefaultView.ToTable() … (5.25 times faster for ds20 and 5.5 for ds35).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ToTable:&amp;#160;&amp;#160;&amp;#160;&amp;#160; 15,406,250 ticks &lt;/li&gt;

  &lt;li&gt;LINQ (ds20):&amp;#160;&amp;#160;&amp;#160; 2,937,500 ticks &lt;/li&gt;

  &lt;li&gt;LINQ (ds35):&amp;#160;&amp;#160;&amp;#160; 2,781,250 ticks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As more columns get added, the LINQ advantage becomes diminished. At some point, the DefaultView.ToTable() methodology becomes preferable. I suspect that that point depends both on the number of columns you wish to have distinct, as well as the number of rows that you are processing. The syntax for the DefaultView.ToTable() becomes slightly different when you have more than one column. Here it is:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:9fbaf271" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt20 = ds20.Personnel.DefaultView
    .ToTable(&lt;span style="color: blue"&gt;true&lt;/span&gt;, &lt;span style="color: blue"&gt;new string&lt;/span&gt;[] { &lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;lastname&amp;quot; &lt;/span&gt;});&lt;/pre&gt;
      &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The LINQ syntax doesn’t change, you just keep adding the columns:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:9fbaf271" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt;();
dt.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;);
dt.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;lastname&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq35 = ds35.Personnel
    .Select(row =&amp;gt;
    {
        &lt;span style="color: #2b91af"&gt;DataRow &lt;/span&gt;newRow = dt.NewRow();
        newRow[&lt;span style="color: #a31515"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;] = row.IsfirstnameNull() ? &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot; &lt;/span&gt;: row.firstname;
        newRow[&lt;span style="color: #a31515"&gt;&amp;quot;lastname&amp;quot;&lt;/span&gt;] = row.IslastnameNull() ? &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot; &lt;/span&gt;: row.lastname;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;newRow;
    }).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default).CopyToDataTable();&lt;/pre&gt;
      &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In the case above, of two columns, &lt;strong&gt;LINQ was just slightly under 5 times faster&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;So, just for giggles, I thought I’d benchmark half the columns. My DataTable has 32 columns, so I tried &lt;strong&gt;a distinct on the first 16 columns &lt;/strong&gt;in my DataTable. And now, it seemed, that we were back to having DefaultView.ToTable() being superior by about 7 times (turns out I was wrong … keep reading). Now, my curiosity got the better of me … I wasted some more time trying to find “the sweet spot” … the number of columns where the performance was about equal. After all, I was a math major in college and I love to play with numbers!&lt;/p&gt;

&lt;p&gt;But, as I played more with this, I discovered something very interesting. The time it takes for LINQ depends on the order of the columns!!! In other words, if the first column in your list doesn’t have a lot of distinct values (mine had 7), but the next one in your list does (mine had 4700+), it will take a lot longer. If you swap the column order of those two columns, BAM! Very fast! Instead of the LINQ query being 7 times slower than the DefaultView.ToTable(), &lt;strong&gt;it was now 2.25 times faster&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Curiously, this doesn’t seem to matter with the DefaultView.ToTable() … it benchmarked the same amount of time with the columns in any order! &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ToTable:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 42,750,000 &lt;/li&gt;

  &lt;li&gt;LINQ (original order of 16 columns):&amp;#160;&amp;#160;&amp;#160; 305,375,000 &lt;/li&gt;

  &lt;li&gt;LINQ (swapped order of columns):&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 19,125,000 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I suspect that my very first test, the one with all the columns,suffered from this anomaly … in other words, the LINQ query was so very much slower because that problem column (the one with only 7 distinct values) happened to be the first column in the DataTable. and the syntax of that query didn’t specify columns. &lt;/p&gt;

&lt;p&gt;After discovering this quirk, I went back and re-ran the LINQ query that used only 2 columns, but I did it this time with these two particular columns where I noticed this problem. Sure enough, with only a two column distinct query, if the columns were in the wrong order, the query slowed to a crawl … becoming &lt;strong&gt;14.5 times slower&lt;/strong&gt; than the DefaultView.ToTable()!!!&amp;#160; Wow!&lt;/p&gt;

&lt;p&gt;So, what’s the takeaway from this little experiment? Good question … I guess it’s that the data makes the difference. If you’re pretty sure about the data in the columns not being too lopsided, distinct-wise, then LINQ is clearly faster for probably all scenarios except the one including all columns (I did not test this, it’s only a guess … the most columns I tested were half). However, if you’re not certain of the distinctness of the data in your columns, perhaps it’s best to stick with the tried-and-true DefaultView.ToTable() method.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7219327261411503186?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7219327261411503186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/09/distinct-linq-versus-dataset.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7219327261411503186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7219327261411503186'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/09/distinct-linq-versus-dataset.html' title='DISTINCT - LINQ versus DataSet'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-5256773820056010502</id><published>2011-04-06T18:19:00.001-07:00</published><updated>2011-04-06T18:19:12.968-07:00</updated><title type='text'>LINQ With DataSets</title><content type='html'>&lt;p&gt;Today's blog post is going to be about using LINQ with DataSets. As anyone who reads my blog regularly (or various forum posts) might already know, I've been a big fan of Typed DataSets since the very beginning of .NET (all the way back to the pretty buggy 1.0 version). However, LINQ is fairly new to me. LINQ &lt;strong&gt;*itself*&lt;/strong&gt; is not new to me ... it has been around for a few years now and I've certainly been aware of it. But I haven't utilized it much because, until .NET 3.5, there was no real support for Typed DataSets and that's really all I wanted to be able to use if for. Sure, you could still use LINQ with both regular DataSets and Typed DataSets ... as long as you used .AsEnumerable() ... but you couldn't take advantage of the Typed nature of a Typed DataSet, so I didn't see any point in messing around with it.&lt;/p&gt;  &lt;p&gt;I've recently begun using it more with Typed DataSets because, surprisingly to me, for some things it seems to be faster. Since .NET 3.5, Typed DataSets have been getting auto-generated slightly different than they have in the past (and I'm not talking about the TableAdapter generation, which I despise ... see my blog post about avoiding that fiasco: &lt;a href="http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html"&gt;http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;Prior to 3.5, the DataTable definition in a generated Typed DataSet looked something like this:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; PersonnelDataTable : global::System.Data.DataTable, global::System.Collections.IEnumerable&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// rest of the code here&lt;/span&gt;&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The minor difference is this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; PersonnelDataTable : global::System.Data.TypedTableBase&amp;lt;PersonnelRow&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// rest of the code here&lt;/span&gt;&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;TypedTableBase is derived from DataTable, so really nothing changes. But, it allows the DataTable to be used in LINQ queries without specifying .AsEnumerable(), allows us to use the Typed column name properties of the DataRows in our LINQ queries &lt;strong&gt;*and*&lt;/strong&gt; it's also much faster. &lt;/p&gt;

&lt;p&gt;As I already mentioned above, LINQ &lt;strong&gt;*can*&lt;/strong&gt; easily be used with regular DataSets/DataTables (it's use is NOT limited to Typed DataSets), but I am not including examples of that in this blog post. As with the 2.0 Typed DataSets, all that is needed is to use .AsEnumerable() with the DataTable, so the code will be almost identical.&lt;/p&gt;

&lt;p&gt;So, let's see a few examples.&lt;/p&gt;

&lt;p&gt;First, let's look at a typical use for a DataSet, selecting some rows. Using LINQ with a Typed DataSet ends up being quite a bit faster than using the DataTable.Select() method. In all my tests, I used a DataTable containing 270,000 rows. The Select in this test, selected 30,000 of those rows. I also did comparisons between 2.0 DataTable and 3.5 TypedTableBase, just for the heck of it.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// ds20 is a 2.0 Typed DataSet, which uses plain a plain old DataTable&lt;/span&gt;&lt;p&gt;&lt;/p&gt;DataRow[] dsSelect20 = ds20.Personnel.Select(&lt;span style="color: #cc6633"&gt;&amp;quot;lastname = 'Berent'&amp;quot;&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;DataRow[] linqSelect = ds20.Personnel.AsEnumerable()&lt;br /&gt; .Where(row =&amp;gt; row.Field&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #cc6633"&gt;&amp;quot;lastname&amp;quot;&lt;/span&gt;) == &lt;span style="color: #cc6633"&gt;&amp;quot;Berent&amp;quot;&lt;/span&gt;)&lt;br /&gt; .Select(row =&amp;gt; row).ToArray();&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The above are your only two choices when using untyped or 2.0 Typed DataSets. Benchmark timing results show that &lt;strong&gt;LINQ is about 6 times faster than the old DataTable.Select() method&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select:&amp;#160; 5,625,000 ticks &lt;/li&gt;

  &lt;li&gt;LINQ:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 937,500 ticks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using 3.5 Typed DataSets, you have a few more options with LINQ. Generally, your LINQ statement will look like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// ds35 is a 3.5 Typed DataSet, which uses the new TypedTableBase class for it's DataTable&lt;/span&gt;&lt;p&gt;&lt;/p&gt;DataRow[] linqSelectLastName = ds35.Personnel&lt;br /&gt; .Where(row =&amp;gt; row.lastname == &lt;span style="color: #cc6633"&gt;&amp;quot;Berent&amp;quot;&lt;/span&gt;)&lt;br /&gt; .Select(row =&amp;gt; row).ToArray();&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Note the differences: you don't need Personnel.AsEnumerable() and you can use the typed row column names, row.lastname. There is one caveat though to the above syntax. If any row in the Personnel table contains DBNull.Value in the lastname column, the above syntax will throw an exception. You must also check for the null, so the actual statement will need to be this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;DataRow[] linqSelectLastName = ds35.Personnel&lt;br /&gt; .Where(row =&amp;gt; row.IslastnameNull() == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt; &amp;amp;&amp;amp; row.lastname == &lt;span style="color: #cc6633"&gt;&amp;quot;Berent&amp;quot;&lt;/span&gt;)&lt;br /&gt; .Select(row =&amp;gt; row).ToArray();&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;You could also use the untyped syntax of the column and then you don't need to check for DBNull, but I like to take advantage of the typed nature of a Typed DataSet. That is the purpose of them, after all. =0) Also, using the untyped syntax is slightly slower, but probably not significantly so.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;DataRow[] linqSelectUntypedLastName = ds35.Personnel&lt;br /&gt; .Where(row =&amp;gt; row.Field&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #cc6633"&gt;&amp;quot;lastname&amp;quot;&lt;/span&gt;) == &lt;span style="color: #cc6633"&gt;&amp;quot;Berent&amp;quot;&lt;/span&gt;)&lt;br /&gt; .Select(row =&amp;gt; row).ToArray();&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Incidentally, my data &lt;strong&gt;*does*&lt;/strong&gt; contain DBNull.Value in the lastname column, so that my benchmark timing tests are valid. The timing for the DataSet.Select() yields roughly the same results either way, but the LINQ is about 1.5 times faster with the TypedTableBase than with a regular DataTable, making &lt;strong&gt;LINQ about 9 times faster than a regular DataSet.Select()!!&lt;/strong&gt;&amp;#160; Here are the results using a 3.5 Typed DataSet:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 5,937,500 ticks &lt;/li&gt;

  &lt;li&gt;LINQ:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 625,000 ticks &lt;/li&gt;

  &lt;li&gt;LINQ (untyped syntax):&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 781,250 ticks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I think that I'll wind up this post for now. There are plenty of other uses of LINQ that I should compare with old DataSet/DataTable functionality, but I think I'll save that for another post. This one is long enough! &lt;/p&gt;

&lt;p&gt;Until next time ... happy coding!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-5256773820056010502?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/5256773820056010502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/04/linq-with-datasets.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5256773820056010502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5256773820056010502'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/04/linq-with-datasets.html' title='LINQ With DataSets'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-6750838341018419145</id><published>2011-01-30T21:57:00.001-08:00</published><updated>2011-01-30T21:57:11.376-08:00</updated><title type='text'>Passing Data Between Forms</title><content type='html'>&lt;p&gt;There are several different approaches one could make to &amp;quot;pass&amp;quot; information, such as a DataSet, from one Form to another. I see this question asked a lot on the forums, so here's a quick summary. You could use one of these approaches, or combine several of them so that the developer has the flexibility to use whichever approach is appropriate. I'm going to show 3 different solutions to the problem: &lt;/p&gt;  &lt;p&gt;First, let's assume we have a MainForm, and it instantiates and shows Form1, and needs to pass a DataSet to it. &lt;/p&gt;  &lt;p&gt;1) Form1 can have a DataSet parameter in its constructor:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Form1 : Form&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DataSet oData;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Form1(DataSet ds)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData = ds;&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000"&gt;// called from MainForm like this:&lt;/span&gt;&lt;br /&gt;Form1 oForm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Form1(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dsCustomer);&lt;br /&gt;oForm.Show();    &lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;2) Form1 can expose its DataSet field as a public Property: &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Form1 : Form&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DataSet oData {get;set;} &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Form1()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000"&gt;// called from MainForm like this:&lt;/span&gt;&lt;br /&gt;Form1 oForm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Form1();&lt;br /&gt;oForm.oData = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dsCustomer;&lt;br /&gt;oForm.Show();    &lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;3) Another option is to use Interfaces. For example, say that your Form1 allows the user to make some changes to the data in the DataSet and you'd like to have MainForm automatically reflect those changes ... even while you're still working in Form1. &lt;/p&gt;

&lt;p&gt;First, let's define the Interface:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IDisplayCustomer&lt;br /&gt;{&lt;br /&gt;    CustomerDataSet dsCustomer {get;set};&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DisplayCustomer();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;MainForm would then be defined like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MainForm : Form, IDisplayCustomer&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CustomerDataSet dsCustomer {get;set;}&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DisplayCustomer()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here to do stuff with this.dsCustomer&lt;/span&gt;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    ...&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// then code elsewhere to instantiate and show Form1:&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dsCustomer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerDataSet(); &lt;span style="color: #008000"&gt;// or other code to fill the dataset&lt;/span&gt;&lt;br /&gt;    Form1 oForm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Form1(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;br /&gt;    oForm.Show();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;And Form1 would look like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Form1 : Form&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; CustomerDataSet oData;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDisplayCustomer CallingControl;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Form1 (IDisplayCustomer callingControl)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CallingControl = callingControl;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData = callingControl.dsCustomer;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoStuff()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code to do stuff with this.oData &lt;/span&gt;&lt;br /&gt;        ...&lt;br /&gt;        &lt;span style="color: #008000"&gt;// and then redisplay in calling form&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CallingControl.DisplayCustomer();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-6750838341018419145?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/6750838341018419145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/01/passing-data-between-forms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6750838341018419145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6750838341018419145'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2011/01/passing-data-between-forms.html' title='Passing Data Between Forms'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7112167429057413687</id><published>2010-12-23T09:03:00.001-08:00</published><updated>2010-12-23T09:03:53.368-08:00</updated><title type='text'>TransactionScope and SqlServer</title><content type='html'>&lt;p&gt;Well, here it is, almost the end of the month, and as usual I’m behind in my blog posting. It seems that I’m lucky to get one post a month this past year. But this month, being almost the end of December, I should at least wish all my readers &lt;strong&gt;“Happy Holidays”.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now, on to today’s topic. This may be old news; after all, TransactionScope has been around since 2.0, but I hadn’t been using it back then. I’ve just really started utilizing it during the past year and recently discovered some interesting gotchas. &lt;/p&gt;  &lt;p&gt;First, let’s start with a little snippet of code:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope())&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// transactional stuff in here, perhaps calls to SQL Server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        ...&lt;br /&gt;&lt;br /&gt;        scope.Complete();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exeception ex)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// do whatever you need to here, we will NOT complete the transaction&lt;/span&gt;&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #cc6633"&gt;&amp;quot;*** ERROR &amp;quot;&lt;/span&gt; + ex.Message);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now, this is all well and good … or so you think. But, there is one little gotcha here …. and that is that when TransactionScope is instantiated without any parameters, the default for its IsolationLevel is Serialized … the most restrictive that there is. On the other hand, for Transactions in SQL Server, the default IsolationLevel is ReadCommitted and, for the most part, that is what you typically will want to use.&lt;/p&gt;

&lt;p&gt;In my case, I’m doing a lot of writing to the database, in lots of different threads. If I don’t mess with the TransactionScope, then IsolationLevel.Serialized will severely slow things down, because the database tables, in effect, get locked … because Serializable prevents new data from being added. Wow, not really what I intended!&lt;/p&gt;

&lt;p&gt;Well, OK, so I guess we can change the above snippet to this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionOptions(){IsolationLevel = IsolationLevel.ReadCommitted}))&lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #008000"&gt;// transactional stuff in here, perhaps calls to SQL Server &lt;/span&gt;&lt;br /&gt;              &lt;br /&gt;        ...        &lt;br /&gt;&lt;br /&gt;        scope.Complete();    &lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exeception ex)    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #008000"&gt;// do whatever you need to here, we will NOT complete the transaction        &lt;/span&gt;&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #cc6633"&gt;&amp;quot;*** ERROR &amp;quot;&lt;/span&gt; + ex.Message);    &lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Wow, that’s messy, but it’s necessary.&lt;/p&gt;

&lt;p&gt;But wait, there’s more!!&amp;#160; If your current transaction is operating under another ambient transaction (“ambient” is like a parent transaction … I don’t know why they didn’t use the same terminology), the IsolationLevel has to be the same! An exception is thrown if it’s not! So, you’ve got to remember to use this same syntax every time you instantiate a TransactionScope! Yuck!&lt;/p&gt;

&lt;p&gt;But, fortunately, there’s a better idea. It’s much easier and cleaner to use a Utility class with static methods for this sort of thing:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Utils&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// The reason for this method to return a TransactionScope is because the default IsolationLevel &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// when not specified is Serializable, which is the most restrictive level and will cause all kinds&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// of deadlock problems with Sql Server!!&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// We can add more overloads later if we want more options.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// The TransactionScoope that gets returned here is Required and IsolationLevel.ReadCommitted.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; TransactionScope GetTransactionScope()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionOptions(){IsolationLevel = IsolationLevel.ReadCommitted});&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;And now, we make sure that all our developers know to always use this method when creating a TransactionScope, like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TransactionScope scope = Utils.GetTransactionScope())&lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #008000"&gt;// transactional stuff in here, perhaps calls to SQL Server &lt;/span&gt;&lt;br /&gt;              &lt;br /&gt;        ...        &lt;br /&gt;&lt;br /&gt;        scope.Complete();    &lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exeception ex)    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #008000"&gt;// do whatever you need to here, we will NOT complete the transaction        &lt;/span&gt;&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #cc6633"&gt;&amp;quot;*** ERROR &amp;quot;&lt;/span&gt; + ex.Message);    &lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Happy Coding and Happy Holidays!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7112167429057413687?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7112167429057413687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/12/transactionscope-and-sqlserver.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7112167429057413687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7112167429057413687'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/12/transactionscope-and-sqlserver.html' title='TransactionScope and SqlServer'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-6852972142206937287</id><published>2010-11-20T17:11:00.001-08:00</published><updated>2010-11-20T17:11:34.477-08:00</updated><title type='text'>ForceBind</title><content type='html'>&lt;p&gt;There are situations in a Windows.Form where the value of a control (such as the value in the .Text property of a TextBox) does not get propagated to its databound object. This can happen as the result of a MenuItem click or a ToolBar button click because these controls do not cause the current control (the ActiveControl, which is the TextBox in my example) to lose focus, thus not forcing the control's value into its databound object. You need something that will force this for every control you have. It can get complicated.&lt;/p&gt;  &lt;p&gt;I have a method that I have named ForceBind() in most of my controls (those that have it implement an Interface I have created for this type of behavior). If the control is a container object that implements that Interface (such as a Panel, UserControl, etc.) it will call the ForceBind() method of *it's* ActiveControl (if *that* control implements the Interface). &lt;/p&gt;  &lt;p&gt;The actual ForceBind() method is pretty complicated in my controls and relies on the fact that I have a DataBind() method on my controls that tell it which DataTable and DataColumn I am binding that control to. However, I've done a little experimenting and I see that we can find other ways of finding those fields. &lt;/p&gt;  &lt;p&gt;I realize that nowadays, most people use a BindingSource rather than Binding directly to a DataTable or DataView. I have not updated my classes yet to differentiate between the various binding DataSources, but in the code I will show below, it is not all that difficult to add that functionality. I leave that as an exercise for the reader …&lt;/p&gt;  &lt;p&gt;Here's the ForceBind() method for MyTextBox (along with the code for determining the m_BoundTable, m_BoundColumn and m_BoundProperty fields):&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DataTable m_BoundTable    = (DataTable)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataBindings[0].DataSource;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;    m_BoundColumn   = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataBindings[0].DataBindings[0].BindingMemberInfo.BindingMember;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; CurrencyManager oCurrency = (CurrencyManager)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BindingContext[m_BoundTable];&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ForceBind()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataBindings.Count == 0)&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; nRow = -1;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_BoundTable != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_BoundColumn != &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCurrency != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            nRow = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCurrency.Position;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (nRow &amp;gt;= 0)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; oValue = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Text;&lt;p&gt;&lt;/p&gt;            System.RuntimeTypeHandle handle = System.Type.GetTypeHandle(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;br /&gt;            System.Type eType = System.Type.GetTypeFromHandle(handle);&lt;p&gt;&lt;/p&gt;            ConvertEventArgs e = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ConvertEventArgs(oValue, eType);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ParseHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, e);&lt;br /&gt;        &lt;br /&gt;            DataRow row = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_BoundTable.DefaultView[nRow].Row;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (row[&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_BoundColumn] != e.Value)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;                {&lt;br /&gt;                    row[&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_BoundColumn] = e.Value;&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception)&lt;br /&gt;                { }&lt;br /&gt;                        &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.OnValidated(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventArgs());&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;You would call this method whenever there's the possibility of an ActiveControl not losing its focus, say in your own base class for your ToolBar Buttons, for example.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-6852972142206937287?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/6852972142206937287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/11/forcebind.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6852972142206937287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6852972142206937287'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/11/forcebind.html' title='ForceBind'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-4467099635902027002</id><published>2010-10-31T21:21:00.001-07:00</published><updated>2010-10-31T21:21:27.939-07:00</updated><title type='text'>Multi-Tier Applications</title><content type='html'>&lt;p&gt;Reading the MSDN forums, I can’t count the number of times I see posters putting all their eggs in one basket, so to speak. Their UI forms contain their Business logic AND their Data Access logic. Their DataSets are defined in the same UI project. Microsoft and Visual Studio, unfortunately, makes this too easy to do … what with all the drag-and-drop stuff from the Server Explorer directly onto a Form designer. I’m sorry, but this is really a great big no-no!!!&lt;/p&gt;  &lt;p&gt;These activities should be broken up into multiple tiers, or layers. To simplify, think of three different projects/dlls in your solution. MyUI, MyBiz, and MyDataAccess (I'd actually throw in a 4th one, MyWebService, but let's not complicate matters at this point. Oh wait, I'd have a separate DataSet project too, but as I said, let's keep it simple for now). In your MyUI project, you'd have all the different forms that you plan to use in your UI. The same for MyBiz and MyDataAccess projects, all the different Biz classes and DataAccess classes. &lt;/p&gt;  &lt;p&gt;So, to start, your form would be similar to this (to get your data when the form first opens):&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; MyCompany.MyApp.Business.MyBiz;&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; MyCompany.MyApp.WinUI.MyUI&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyForm : MyBaseForm&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt;          CustomerKey;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; MyDataSet     dsData;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; CustomerBiz   oBiz;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyForm(&lt;span style="color: #0000ff"&gt;long&lt;/span&gt; key)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CustomerKey = key;&lt;br /&gt;      InitializeComponent();&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FillData();&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FillData()&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color: #008000"&gt;// To simplify, I'm directly calling a Biz class.&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #008000"&gt;// In reality, I use a Web Service here instead&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #008000"&gt;// which in turn calls the Biz class.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;      oBiz = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerBiz();&lt;br /&gt;      dsData = oBiz.GetCustomer(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CustomerKey);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Now in your MyBiz project, you'd have a Biz class:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; MyCompany.MyApp.DataAccess.MyDataAccess&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; MyCompany.MyApp.Business.MyBiz&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; CustomerBiz&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; MyDataSet dsData;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; MyDataSet GetCustomer(&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; CustomerKey)&lt;br /&gt;    {&lt;br /&gt;      CustomerAccess oDA = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CustomerAccess();&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.dsData = oDA.GetCustomer(CustomerKey);&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #008000;"&gt;// if you have other Biz things to do to this customer&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #008000;"&gt;// do it here before returning the DataSet&lt;/span&gt;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.dsData;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;And, lastly, in your MyDataAccess project, you'd have this class:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; MyCompany.MyApp.DataAccess.MyDataAccess&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; CustomerAccess&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; MyDataSet GetCustomer(&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; CustomerKey)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color: #008000;"&gt;// Here's where you'd put all the SqlCommand and DataAdapter stuff&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #008000;"&gt;// and fill your DataSet.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; dsData;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now, that's the "simple" version, just to get the concept. Let's take it a step further:&lt;/p&gt;

&lt;p&gt;We have 4 "layers" ... UI, Web Services, Business, Data Access.&lt;/p&gt;

&lt;p&gt;These are more than 4 projects, because each layer is further broken down by module. Let's take the DataAccess layer as an example:&lt;/p&gt;

&lt;p&gt;As in all our layers, there are DataAccess parent classes from which all DataAccess classes inherit. These parent classes have all the basic functionality needed for DataAccess and we consider it part of our "framework" ... it has it's own project. See my 3-part DataAccess series for more info about this: &lt;/p&gt; 

&lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html" target="_blank"&gt;http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html&lt;/a&gt;&lt;br&gt;
&lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html" target="_blank"&gt;http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html&lt;/a&gt;&lt;br&gt;
&lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html" target="_blank"&gt;http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html&lt;/a&gt;&lt;br&gt;

&lt;p&gt;Each module in our app has a separate DataAccess project. So, we'll have a DataAccess.Personnel project and a DataAccess.Inspection project, etc. and the classes in those projects inherit from the parent classes in the "framework" project. (As you probably know, these separate projects become separate .DLLs).&lt;/p&gt;

&lt;p&gt;The Business layer got a little more complicated, but the architecture of it is the same. We actually have 2 Business layers ... server-side and client-side. The server-side classes remain on the server where they are accessed from the Web Services. The client-side classes are brought down to the client from the server to be used by the UI classes, but they can also be used on the server. &lt;/p&gt;

&lt;p&gt;So, that's it in a nutshell. I think it's a good start, to get you thinking about how you should structure your application.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-4467099635902027002?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/4467099635902027002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/10/multi-tier-applications.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/4467099635902027002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/4467099635902027002'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/10/multi-tier-applications.html' title='Multi-Tier Applications'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-5083364077975335862</id><published>2010-10-23T17:26:00.001-07:00</published><updated>2010-10-23T17:26:22.293-07:00</updated><title type='text'>Exception Handling</title><content type='html'>&lt;p&gt;Today’s post is about having “global” Exception handling at the Application Level. What I mean by that is handling an exception at the very &amp;quot;top&amp;quot; of an application, in your MainForm, in case exception handling as been missed by the developer in other modules, forms or whatever. Something like this will do it:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;[STAThread]&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// Creates an instance of the methods that will handle the exception.&lt;/span&gt;&lt;br /&gt;    CustomExceptionHandler eh = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CustomExceptionHandler();&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000;"&gt;// Adds the event handler to to the event.&lt;/span&gt;&lt;br /&gt;    Application.ThreadException += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ThreadExceptionEventHandler(eh.OnThreadException);&lt;br /&gt;    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);&lt;br /&gt;    &lt;br /&gt;    Application.Run(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MainForm());&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000;"&gt;// Creates a class to handle the exception event.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; CustomExceptionHandler&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// Handles the exception event.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnThreadException(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, ThreadExceptionEventArgs t)&lt;br /&gt;    {&lt;br /&gt;        DialogResult result = &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.ShowThreadExceptionDialog(t.Exception);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000;"&gt;// Exits the program after displaying message to the user. &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// In Development mode, the developer will have more options (Abort/Retry/Ignore).&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (result == DialogResult.OK || result == DialogResult.Abort)&lt;br /&gt;            Application.Exit();&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000;"&gt;// Creates the error message and displays it.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; DialogResult ShowThreadExceptionDialog(Exception e)&lt;br /&gt;    {&lt;br /&gt;        DialogResult retval;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; msgUser  = &lt;span style="color: #cc6633;"&gt;"An error occurred please contact the adminstrator with the following information:\n\n"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; msgDev   = &lt;span style="color: #cc6633;"&gt;"An unhandled exception occurred (Abort/Retry/Ignore buttons are only displayed to Developers) \n\n"&lt;/span&gt;;&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; msgTrace = &lt;span style="color: #cc6633;"&gt;"Error: "&lt;/span&gt; + e.Message + &lt;span style="color: #cc6633;"&gt;"\n\n"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (e.InnerException != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            msgTrace   += &lt;span style="color: #cc6633;"&gt;"       "&lt;/span&gt; + e.InnerException.Message + &lt;span style="color: #cc6633;"&gt;"\n\n"&lt;/span&gt;;&lt;br /&gt;        msgTrace += &lt;span style="color: #cc6633;"&gt;"Error Method: "&lt;/span&gt; + e.TargetSite + &lt;span style="color: #cc6633;"&gt;"\n\n"&lt;/span&gt; +&lt;br /&gt;                    &lt;span style="color: #cc6633;"&gt;"Stack Trace: "&lt;/span&gt;  + e.StackTrace;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (System.Diagnostics.Debugger.IsAttached)&lt;br /&gt;            retval = MessageBox.Show(msgDev + msgTrace, &lt;span style="color: #cc6633;"&gt;"Application Error"&lt;/span&gt;, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation);&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;            retval = MessageBox.Show(msgUser + msgTrace, &lt;span style="color: #cc6633;"&gt;"Application Error"&lt;/span&gt;, MessageBoxButtons.OK, MessageBoxIcon.Stop);&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; retval;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

You'll notice that in my example, I only allow the user to Retry or Ignore if they're the developer and debugging. I assume that in such a case, the developer will want to see right off the bat what went wrong and where, but if this happens to a real user, it's typically NOT a good idea to allow them to continue, as it may easily lead to further corruption of data. You can also expand on this class to add error-logging or whatever you wish.
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-5083364077975335862?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/5083364077975335862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/10/exception-handling.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5083364077975335862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5083364077975335862'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/10/exception-handling.html' title='Exception Handling'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-6872908245780480702</id><published>2010-09-26T15:14:00.001-07:00</published><updated>2010-09-26T15:14:31.759-07:00</updated><title type='text'>Hook Into Form’s Events From Controls On Form</title><content type='html'>&lt;p&gt;Today’s blog post will be another excerpt from my &lt;a href="http://www.universalthread.com/ViewPageArticle.aspx?Session=4A58784F6F516C6C4847633D206E5674554E70574B63584C73567332773173743553513D3D" target="_blank"&gt;.Net Tips&lt;/a&gt; column in the &lt;a href="http://www.universalthread.com/ViewPageMainPage.aspx?Session=69386A366B6559304966553D20695374685649646F4C664A4B2B726838454A4B6B71513D3D" target="_blank"&gt;March 2008 Issue&lt;/a&gt; of the &lt;a href="http://www.universalthread.com/ViewPageIssue.aspx" target="_blank"&gt;Universal Thread Magazine&lt;/a&gt;.&lt;/p&gt;  Following is one methodology one could use to accomplish hooking into Form events from a Control.  &lt;BR&gt;&lt;BR&gt; Let's use an example to illustrate this ... we'd like our Control to hook into the Form's Load and Closing events. Let's use the ListView as an example. First, we'll sub-class the ListView Control.  As you can see we override the OnParentChanged event in the ListView sub-class.  &lt;BR&gt;&lt;BR&gt; We utilize the TopLevelControl (not the Parent). If the TopLevelControl is null then we  hookup event handlers backwards through the control hierarchy as each control is parented.  When we finally get to a TopLevelControl for a Form type we hookup the load/close event  handlers.&lt;BR&gt;  &lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; MyListView : System.Windows.Forms.ListView&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; Form _parentForm = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; MyListView()&lt;br /&gt;   {&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnParentChanged(EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;.OnParentChanged(e);&lt;br /&gt;            &lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.DesignMode == &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.TopLevelControl != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; &amp;amp;amp;&amp;amp;amp; &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.TopLevelControl &lt;span style="color: #0000ff;"&gt;is&lt;/span&gt; Form)&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm = (Form)&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.TopLevelControl;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.EstablishParentEvents();&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;         {&lt;br /&gt;            Control LastParent = &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;(LastParent != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;               LastParent.ParentChanged += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(LastParent_ParentChanged);&lt;br /&gt;               LastParent = LastParent.Parent;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; EstablishParentEvents()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm.Closing += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancelEventHandler(MyListView_Closing);&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm.Load += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(MyListView_Load);&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; MyListView_Closing(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, CancelEventArgs e)&lt;br /&gt;   {&lt;br /&gt;      MessageBox.Show(&lt;span style="color: #cc6633;"&gt;"The parent form is closing!"&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm.Closing -= &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancelEventHandler(MyListView_Closing);&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm.Load -= &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(MyListView_Load);&lt;br /&gt;      }&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; MyListView_Load(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      MessageBox.Show(&lt;span style="color: #cc6633;"&gt;"The parent form is loading!"&lt;/span&gt;);&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LastParent_ParentChanged(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      Control Source = (Control)sender;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (Source.TopLevelControl != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; &amp;amp;amp;&amp;amp;amp; Source.TopLevelControl &lt;span style="color: #0000ff;"&gt;is&lt;/span&gt; Form)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;._parentForm = (Form)Source.TopLevelControl;&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.EstablishParentEvents();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;


&lt;p&gt;Thanks to Neil Tonkin in Message #1084683 on the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-6872908245780480702?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/6872908245780480702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/09/hook-into-forms-events-from-controls-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6872908245780480702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6872908245780480702'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/09/hook-into-forms-events-from-controls-on.html' title='Hook Into Form’s Events From Controls On Form'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-2000210523706447777</id><published>2010-08-29T16:31:00.001-07:00</published><updated>2010-08-29T16:31:00.360-07:00</updated><title type='text'>Interesting Clipboard Functionality</title><content type='html'>&lt;p&gt;Last week’s blog post was an excerpt from my &lt;a href="http://www.universalthread.com/ViewPageArticle.aspx?Session=626265685A64644F4465593D2071685058364851527941377A38456E652B31784339413D3D" target="_blank"&gt;.Net Tips&lt;/a&gt; column in the &lt;a href="http://www.universalthread.com/ViewPageMainPage.aspx?Session=7641586E4F6B586F77304D3D20515A4463594754486B627071336F5132784A392F78413D3D" target="_blank"&gt;April 2008 Issue&lt;/a&gt; of the &lt;a href="http://www.universalthread.com/ViewPageIssue.aspx" target="_blank"&gt;Universal Thread Magazine&lt;/a&gt;. Well, that was such a good issue for Tips, that I'm going to post another one from the same issue. I hope no one minds!  ;0) &lt;/p&gt;  &lt;p&gt;Did you ever need to copy an instantiated class to the clipboard, retreive it  and access a property or method on it? Well, here's how to do it:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;Clipboard.SetData(&lt;span style="color: #cc6633;"&gt;"MyClassFormat"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MyClass(&lt;span style="color: #cc6633;"&gt;"42"&lt;/span&gt;));&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (Clipboard.ContainsData(&lt;span style="color: #cc6633;"&gt;"MyClassFormat"&lt;/span&gt;))&lt;br /&gt;{&lt;br /&gt;    MyClass o = Clipboard.GetData(&lt;span style="color: #cc6633;"&gt;"MyClassFormat"&lt;/span&gt;) &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt; MyClass;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (o != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// do stuff here, such as execute a method&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// o.MyMethod();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// or set a property&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;// o.MyProperty = "xyz";&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    MessageBox.Show(&lt;span style="color: #cc6633;"&gt;"Ain't nothing there!!"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;There's only one gotcha and that is that &lt;b&gt;your class must have the [Serializable] attribute&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to Einar Kvandahl in Message #1135004 on the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-2000210523706447777?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/2000210523706447777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/08/interesting-clipboard-functionality.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2000210523706447777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2000210523706447777'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/08/interesting-clipboard-functionality.html' title='Interesting Clipboard Functionality'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-8353069737942146379</id><published>2010-08-22T16:56:00.001-07:00</published><updated>2010-08-22T16:56:32.759-07:00</updated><title type='text'>Determine new PK after an Insert</title><content type='html'>&lt;p&gt;Today’s blog post will be another excerpt from my &lt;a href="http://www.universalthread.com/ViewPageArticle.aspx?Session=626265685A64644F4465593D2071685058364851527941377A38456E652B31784339413D3D" target="_blank"&gt;.Net Tips&lt;/a&gt; column in the &lt;a href="http://www.universalthread.com/ViewPageMainPage.aspx?Session=7641586E4F6B586F77304D3D20515A4463594754486B627071336F5132784A392F78413D3D" target="_blank"&gt;April 2008 Issue&lt;/a&gt; of the &lt;a href="http://www.universalthread.com/ViewPageIssue.aspx" target="_blank"&gt;Universal Thread Magazine&lt;/a&gt;.&lt;/p&gt;  You have a couple of options to get the PK value of a newly inserted record. I  am assuming SQL Server database in these examples.  &lt;br&gt;&lt;br&gt; First, if you are not using Stored Procs and simply sending an INSERT INTO  statement, just add a "SELECT SCOPE_IDENTITY() at the end of your query and be  sure to execute your query by reading the result back (into a datareader or  dataset for example).  &lt;BR&gt;&lt;BR&gt; Your query string should look like this: &lt;br&gt;&lt;br&gt;  &lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Sql = &lt;span style="color: #cc6633;"&gt;"INSERT INTO MyTable (ColumnOne) VALUES ('Bob') SELECT SCOPE_IDENTITY() AS MyPK"&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

And, here's the code that shows how to execute and read the results back using 
a DataReader:&lt;br&gt;&lt;br&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; MyPK = 0;&lt;br /&gt;SqlCommand sc = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SqlCommand(Sql, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SqlConnection(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.TestConnection));&lt;br /&gt;sc.Connection.Open();&lt;br /&gt;SqlDataReader rd = sc.ExecuteReader(CommandBehavior.CloseConnection);&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt; (rd.Read())&lt;br /&gt;{&lt;br /&gt;  MyPK = Convert.ToInt32(rd[&lt;span style="color: #cc6633;"&gt;"MyPK"&lt;/span&gt;]);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

Alternatively, if you're using a Stored Proc, you'd use an OUTPUT parameter in 
your Stored Proc, and a ParameterDirection.InputOutput in your code: &lt;br&gt;&lt;br&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #008000;"&gt;-- The Stored Proc&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;PROCEDURE&lt;/span&gt; MySP &lt;br /&gt;          @PK        &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;     = &lt;span style="color: #0000ff;"&gt;NULL&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;OUTPUT&lt;/span&gt;,&lt;br /&gt;          @ColumnOne &lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;(8) = &lt;span style="color: #0000ff;"&gt;NULL&lt;/span&gt;,&lt;br /&gt;          @ColumnTwo &lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;(4) = &lt;span style="color: #0000ff;"&gt;NULL&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;AS&lt;/span&gt;&lt;br /&gt;  INSERT MyTable (ColumnOne, ColumnTwo)&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;SELECT&lt;/span&gt; @ColumnOne, @ColumnTwo&lt;p&gt;&lt;/p&gt;  &lt;span style="color: #0000ff;"&gt;SELECT&lt;/span&gt; @PK = SCOPE_IDENTITY()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

And here's how you would call it in your code:&lt;br&gt;&lt;br&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;Command.CommandText = &lt;span style="color: #cc6633;"&gt;"MySP"&lt;/span&gt;;&lt;br /&gt;Command.Parameters.Add(&lt;span style="color: #cc6633;"&gt;"@PK"&lt;/span&gt;, 0);&lt;br /&gt;Command.Parameters[&lt;span style="color: #cc6633;"&gt;"@PK"&lt;/span&gt;].Direction = ParameterDirection.InputOutput;&lt;br /&gt;Command.Parameters.Add(&lt;span style="color: #cc6633;"&gt;"@ColumnOne"&lt;/span&gt;, OneValue);&lt;br /&gt;Command.Parameters.Add(&lt;span style="color: #cc6633;"&gt;"@ColumnTWo"&lt;/span&gt;, TwoValue);&lt;p&gt;&lt;/p&gt;Command.ExecuteNonQuery();&lt;p&gt;&lt;/p&gt;MyNewPK = Command.Parameters[&lt;span style="color: #cc6633;"&gt;"@PK"&lt;/span&gt;].Value;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

Thanks to Éric Moreau (and another post by me) in Messages #1090511 and #930339 on the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-8353069737942146379?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/8353069737942146379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/08/determine-new-pk-after-insert.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8353069737942146379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8353069737942146379'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/08/determine-new-pk-after-insert.html' title='Determine new PK after an Insert'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-1471649898257565118</id><published>2010-07-31T18:04:00.001-07:00</published><updated>2010-07-31T18:04:31.497-07:00</updated><title type='text'>Security Issues with EventSources in EventLogs</title><content type='html'>&lt;p&gt;If you rely on the System.Diagnostics.EventLog class to log your server-side errors (such as those that may occur in a web service), you may run into security issues if you try to use an EventSource that doesn’t already exist. Since this is server-side, the easiest thing to do is to use a Web Service web method, which can just be accessed through IE.It only needs to be done once. Here's the web method: &lt;/p&gt;  &lt;p&gt;The line containing &amp;quot;Events.EventSources&amp;quot; is simply an Enum containing the names of EventSources you might use in your app. If you only have one, then you can just get rid of that whole foreach loop and just hardcode the name of your source in the if.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;[WebMethod(Description = &lt;span style="color: #cc6633"&gt;&amp;quot;Set server Event Log sources.&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SetEventLogSources(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Username, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Password, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Domain)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;//This will keep track of the impersonation token&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; LOGON_TYPE_INTERACTIVE = 2;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; LOGON_TYPE_PROVIDER_DEFAULT = 0;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; logName = &lt;span style="color: #cc6633"&gt;&amp;quot;Application&amp;quot;&lt;/span&gt;;&lt;br /&gt;    IntPtr userToken = IntPtr.Zero;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (LogonUser(Username, Domain, Password, LOGON_TYPE_INTERACTIVE, LOGON_TYPE_PROVIDER_DEFAULT, &lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; userToken))&lt;br /&gt;        {&lt;br /&gt;        &lt;span style="color: #008000"&gt;//Initialize user token &lt;/span&gt;&lt;br /&gt;        WindowsIdentity oIdentity = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WindowsIdentity(userToken);&lt;br /&gt;        WindowsImpersonationContext oContext = oIdentity.Impersonate();&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; source &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Enum.GetNames(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Events.EventSources)))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (EventLog.SourceExists(source) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;                EventLog.CreateEventSource(source, logName);&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000"&gt;//Undo impersonation&lt;/span&gt;&lt;br /&gt;        oContext.Undo();&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;Event source registration successful!&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;Unable to process user credentials for event source registration.&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000"&gt;// Using this api to get an accessToken of specific Windows User by its user name and password    &lt;/span&gt;&lt;br /&gt;[DllImport(&lt;span style="color: #cc6633"&gt;&amp;quot;advapi32.dll&amp;quot;&lt;/span&gt;, CharSet = CharSet.Unicode, SetLastError = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;extern&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; LogonUser(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; userName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; domain, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; passWord, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; logonType, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; logonProvider, &lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; IntPtr accessToken);&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Be sure you have included the following “using”s:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Security.Principal;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Runtime.InteropServices;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-1471649898257565118?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/1471649898257565118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/07/security-issues-with-eventsources-in.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1471649898257565118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1471649898257565118'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/07/security-issues-with-eventsources-in.html' title='Security Issues with EventSources in EventLogs'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7659185719883879627</id><published>2010-06-05T18:08:00.001-07:00</published><updated>2010-06-05T18:08:26.273-07:00</updated><title type='text'>Program To The Interface</title><content type='html'>&lt;p&gt;One of the biggest benefits of using Interfaces (in my opinion) is to be able to &amp;quot;program to the Interface&amp;quot;, as they say. Let me explain with a real-world example: &lt;/p&gt;  &lt;p&gt;Suppose I have created this Interface:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IFillFromFinder&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FillListView(DataSet dsList);&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClearListView();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now, suppose I have a class that contains a ListView and implements the Interface:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MySearchClass : MyUserControl, IFillFromFinder&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; ListView     oListView;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; MyFinderForm oFinder;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Methods&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Search(ListView listView)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oListView = listview;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClearListView();&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oFinder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyFinderForm(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;br /&gt;        oFinder.ShowDialog();&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Interface methods to implement &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClearListView()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here for clearing listview&lt;/span&gt;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FillListView(DataSet dsList)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here for filling listview&lt;/span&gt;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;As you can see, this class calls a Finder dialog Form, that gathers information from the User and performs a query against the backend data. If the Finder Dialog has been called from a control that implements this Interface (as in the above call from the Search() method), then it can also fill that control's ListView object by calling the methods on the Interface. &lt;/p&gt;

&lt;p&gt;Here's the relevant part of my Finder Dialog. Note that the oListControl is defined using the Interface. MyFinderForm needs to know absolutely nothing else about what's calling it, other than that it implements the IFillFromFinder interface.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyFinderForm : MyDialogForm    &lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyListDataSet oData = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyListDataSet();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IFillFromFinder oListControl = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Constructors&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyFinderForm(IFillFromFinder CallingControl)&lt;br /&gt;    {            &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oListControl = CallingControl;            &lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }        &lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyFinderForm()        &lt;br /&gt;    {            &lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Events&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; cmdOK_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FillDataSet();&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000"&gt;// If this dialog form was called by a class that implemented IFillFromFinder, &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// then call call the Interface method to fill the ListView.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oListControl != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.chkReplace.Checked == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oListControl.ClearListView();&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oListControl.FillListView(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData);&lt;br /&gt;        }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here's another good example. Suppose I need to perform some kind of action, or access a property, on a Control on my Form, but not all Controls on my Form have the appropriate method or property. Interfaces come in handy for this, as these two examples illustrate:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (IMyControl control &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Controls)&lt;br /&gt;{&lt;br /&gt;    control.MyMethod();&lt;br /&gt;    control.MyProperty = &lt;span style="color: #cc6633"&gt;&amp;quot;whatever&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;-or-&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (SomeControl &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; IMyControl)&lt;br /&gt;{&lt;br /&gt;    ((IMyControl)SomeControl).MyMethod();&lt;br /&gt;    ((IMyControl)SomeControl).MyProperty = &lt;span style="color: #cc6633"&gt;&amp;quot;whatever&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;I hope this sort of helps explain interfaces by using a real world example.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7659185719883879627?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7659185719883879627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/06/program-to-interface.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7659185719883879627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7659185719883879627'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/06/program-to-interface.html' title='Program To The Interface'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-308553589029967267</id><published>2010-05-18T13:12:00.001-07:00</published><updated>2010-05-18T13:12:24.862-07:00</updated><title type='text'>Inheritance and Constructors</title><content type='html'>&lt;p&gt;Here's a common scenario: say you have a base class that does some work that relies on the setting of one of its properties. In the example I'll show, I have an abstract class designed to fill a DataSet from SQL, based on the TableName member of the class.   &lt;br /&gt;Each sub-class will set TableName, because each sub-class will be filling it's own table.&lt;/p&gt;  &lt;p&gt;Our first attempt at creating these two classes looks like this:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;br /&gt;&lt;/div&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BizObj&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TableName=&lt;span style="color: #cc6633"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DataSet oData;&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BizObj()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LoadData();  &lt;br /&gt;   }   &lt;br /&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadData()&lt;br /&gt;   {&lt;br /&gt;      SqlConnection oConn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(&lt;span style="color: #cc6633"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;);&lt;br /&gt;      SqlDataAdapter oAdapter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(&lt;span style="color: #cc6633"&gt;&amp;quot;SELECT * FROM &amp;quot;&lt;/span&gt; + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TableName, oConn);&lt;br /&gt;      oAdapter.Fill(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AuthorBizObj: BizObj&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; AuthorBizObj()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TableName=&lt;span style="color: #cc6633"&gt;&amp;quot;Authors&amp;quot;&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This does not work. Why? Because when instantiating any class, its base class constructor always fires first. My example used an abstract base class, but the same applies to a non-abstract class. So, in this example, the BizObj (base class) constructor fires before the AuthorBizObj (sub-class) constructor. By then, it's too late to set the TableName (which has already been set in the BizObj base class).&lt;/p&gt;

&lt;p&gt;The trick to fixing this is to use a virtual Property, rather than a member, and to override that Property in each sub-class:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BizObj&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TableName { get; set; }&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DataSet oData;&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BizObj()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LoadData();&lt;br /&gt;   }&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadData()&lt;br /&gt;   {&lt;br /&gt;      SqlConnection oConn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(&lt;span style="color: #cc6633"&gt;&amp;quot;...&amp;quot;&lt;/span&gt;);&lt;br /&gt;      SqlDataAdapter oAdapter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(&lt;span style="color: #cc6633"&gt;&amp;quot;SELECT * FROM &amp;quot;&lt;/span&gt; + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TableName, oConn);&lt;br /&gt;      oAdapter.Fill(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AuthorBizObj: BizObj&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TableName&lt;br /&gt;   {&lt;br /&gt;      get {&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &amp;quot;Authors;}&lt;br /&gt;   }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; AuthorBizObj()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// whether or not you have this constructor&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// does not affect the how the constructor fires&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// I left a non-functional constructor in this example&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// simply for illustrative purposes. You can leave it&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// out if you have nothing to code in it.&lt;/span&gt;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;So, there are two important points to take away from the above illustration:&lt;/p&gt;

&lt;p&gt;1) When a class has been sub-classed, the base class constructor &lt;strong&gt;always&lt;/strong&gt; runs &lt;strong&gt;before&lt;/strong&gt; the sub-class constructor.&lt;/p&gt;

&lt;p&gt;2) The member variables are instanced&amp;#160; in just the opposite order:&amp;#160; the base class member variables are set &lt;strong&gt;after&lt;/strong&gt; the sub-class member variables (the above examples don’t quite illustrate this point). Keep in mind, I’m talking about member variables (which cannot be virtual and so cannot be overridden in a sub-class). My examples above used virtual properties (with getters/setters), which aren’t set until they’re accessed.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-308553589029967267?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/308553589029967267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/05/inheritance-and-constructors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/308553589029967267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/308553589029967267'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/05/inheritance-and-constructors.html' title='Inheritance and Constructors'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-2309461626144038125</id><published>2010-04-18T09:14:00.001-07:00</published><updated>2010-04-18T09:14:08.718-07:00</updated><title type='text'>Create An XSD</title><content type='html'>&lt;p&gt;In a post I wrote back in September about why I dislike TableAdapters (see &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/tableadapters-are-crap.html" target="_blank"&gt;TableAdapters Are Crap&lt;/a&gt;), I mentioned that the TableAdapter wizard puts a lot of excess stuff in your .xsd that doesn’t belong there. So, how do you avoid that? Well, first you’ve got to have already created an .xsd. I’ll show an easy little utility you can write yourself to use to do this.&lt;/p&gt;  &lt;p&gt;Secondly, you’ve got to avoid using the DataSet Designer in such a way that it puts all that excess stuff into your .xsd. How do you do that? That’s pretty easy actually … as long as you don't open an .xsd with the DataSet Designer, but open it with the XML Editor instead, you won't have to worry about getting all the extra stuff for support of TableAdapters generated in your .xsd (it's not the opening, but the saving of changes that generates the code).&lt;/p&gt;  &lt;p&gt;So, use the code I’ll show you in a moment to create an .xsd. Then, simply add that .xsd to your DataSet project, right-click on the .xsd and choose &amp;quot;Run Custom Tool&amp;quot;. This is what will generate the Typed DataSet for you. If that option doesn't show up in your context menu, choose Properties instead and type &amp;quot;MSDataSetGenerator&amp;quot; in the Custom Tool property. After that, any time you make a change to the .xsd in the XML Editor and save the change, the Typed DataSet gets regenerated.&lt;/p&gt;  &lt;p&gt;Now, on to the code … this example is fairly simple but quite usable. You can make it more robust if you want to (for example, add code to find other SQL Servers rather than use only a default) . Create a Form, put 3 textboxes and a button on it. Don’t forget that you need to add a “using System.Data.SqlClient;” in order to use the SQL stuff.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FormCreateXsd : Form&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TestConnection = &lt;span style="color: #cc6633"&gt;&amp;quot;server=(local);uid=sa;pwd=MyPassword&amp;quot;&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FormCreateXsd()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateDataSet()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// set up the connection with the database name&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; connectionString = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TestConnection + &lt;span style="color: #cc6633"&gt;&amp;quot;;database=&amp;quot;&lt;/span&gt; + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtDatabaseName.Text;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// set up the Sql Command and DataAdapter with the Stored Proc name&lt;/span&gt;&lt;br /&gt;            SqlCommand sc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtStoredProcName.Text, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(connectionString));&lt;br /&gt;            sc.CommandType = CommandType.StoredProcedure;&lt;br /&gt;            SqlDataAdapter da = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(sc);&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #008000"&gt;// set up the DataSet with the DataSet name&lt;/span&gt;&lt;br /&gt;            DataSet ds = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataSet();&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] parts = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtDataSetName.Text.Split(&lt;span style="color: #cc6633"&gt;'.'&lt;/span&gt;);&lt;br /&gt;            ds.DataSetName = parts[0];&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #008000"&gt;// and fill the DataSet&lt;/span&gt;&lt;br /&gt;            da.Fill(ds);&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #008000"&gt;// set the filename and write out the schema&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; filename = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtDataSetName.Text;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (parts[parts.Length - 1].ToLower() != &lt;span style="color: #cc6633"&gt;&amp;quot;xsd&amp;quot;&lt;/span&gt;)&lt;br /&gt;                filename += &lt;span style="color: #cc6633"&gt;&amp;quot;.xsd&amp;quot;&lt;/span&gt;;&lt;br /&gt;            ds.WriteXmlSchema(filename);&lt;br /&gt;            MessageBox.Show(filename + &lt;span style="color: #cc6633"&gt;&amp;quot; successfully created&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; msg = ex.Message;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ex.InnerException != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                msg += &lt;span style="color: #cc6633"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; + ex.InnerException.Message;&lt;br /&gt;            MessageBox.Show(&lt;span style="color: #cc6633"&gt;&amp;quot;The following error occurred: &amp;quot;&lt;/span&gt; + ex.Message);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; button1_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtDatabaseName.Text == &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt; || &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtDataSetName.Text == &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt; || &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtStoredProcName.Text == &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CreateDataSet();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;That’s it. Happy coding!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-2309461626144038125?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/2309461626144038125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html#comment-form' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2309461626144038125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2309461626144038125'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html' title='Create An XSD'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-1198088647916366476</id><published>2010-03-28T14:32:00.001-07:00</published><updated>2010-06-21T07:11:16.981-07:00</updated><title type='text'>Custom Events</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;font color="#FF0000"&gt;UPDATE:&lt;/font&gt;&lt;/strong&gt; I've updated my examples below, and added to some of the text, to take into account tergiver's suggestion, in his comment below, that I should probably use the generic EventHandler&lt;TEventArgs&gt; delegate (introduced in .NET 2.0) rather than defining custom delegates (which dates back to .NET 1.x). In fact, I've totally taken out the custom delegate code, since I doubt many people are still using .NET 1.1 anymore. If anyone reading this who is not using .NET 2.0 and higher would like to know about the custom delegate declarations and usage, let me know in a comment.&lt;/p&gt; &lt;p&gt;I tend to write introductory topics in my blog. Not always, but typically. And not because I’m a newcomer to .NET (I’ve been using .NET since the beginning of 2002), but because all the complicated topics seem to be covered by everyone else and I think there is still a need to address simpler topics. &lt;/p&gt;  &lt;p&gt;Today’s topic is no different. Even though writing custom events isn’t all that complicated, I still see a lot of questions on the Forums asking how to do it. So, let’s get to it.&lt;/p&gt;  &lt;p&gt;Say you have a custom UserControl that you need to have raise an event when, for example, a user types &amp;quot;FOO&amp;quot; in a textbox that is on the Control. &lt;/p&gt;  &lt;p&gt;Minimally, in your UserControl, you need the following things:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #008000;"&gt;// First you must specify the event that you will be raising:
&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;event&lt;/span&gt; EventHandler MyFooBar;&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000;"&gt;// Then, when you need to fire the event in your UserControl, do this:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.MyTextBox.Text == &lt;span style="color: #cc6633;"&gt;"FOO"&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.OnMyFooBar(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventArgs());&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000;"&gt;// Lastly, this raises the MyFooBar event:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnMyFooBar(EventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (MyFooBar != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        MyFooBar(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;, e);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Then, in your form, you just set up the usual delegates and EventHandlers:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl.MyFooBar += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; System.EventHandler(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl_MyFooBarHandler);&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; oMyControl_MyFooBarHandler(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// whatever your form code needs to be, such as:&lt;/span&gt;&lt;br /&gt;    MessageBox.Show(&lt;span style="color: #cc6633;"&gt;"FOO was specified!"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Or, the alternative way to do this since anonymous methods were introduced in 2.0:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl.MyFooBar += &lt;span style="color: #0000ff;"&gt;delegate&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// whatever your code needs to be, such as&lt;/span&gt;&lt;br /&gt;    MessageBox.Show(&lt;span style="color: #cc6633;"&gt;"FOO was specified!"&lt;/span&gt;);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;You can even get more fancy, creating custom EventArgs and utilizing generic delegates, but the above code is sufficient for simple things, when just the built-in System.EventArgs is all you need. For fancier, custom stuff, try this: &lt;/p&gt;

&lt;p&gt;First, custom event args something like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; MyCustomEventArgs : EventArgs &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; IsBarSpecified { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Your UserControl code then gets changed to this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #008000;"&gt;// Change the event so that it can be handled by a generic delegate
&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;event&lt;/span&gt; EventHandler&amp;ltMyCustomEventArgs&amp;gt MyFooBar;&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000;"&gt;// Firing the event gets changed to something like this:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.MyTextBox.Text.ToUpper().Contains(&lt;span style="color: #cc6633;"&gt;"FOO"&lt;/span&gt;))&lt;br /&gt;{&lt;br /&gt;    MyCustomEventArgs e = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MyCustomEventArgs();&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.MyTextBox.Text.ToUpper().Contains(&lt;span style="color: #cc6633;"&gt;"BAR"&lt;/span&gt;))&lt;br /&gt;        e.IsBarSpecified = &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br /&gt;        e.IsBarSpecified = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.OnMyFooBar(e);&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000;"&gt;//And raising the MyFooBar event is the same, other than changing to the custom EventArgs:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnMyFooBar(MyCustomEventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; MyFooBar != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        MyFooBar(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;, e);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;And in your Form, you'd have this instead:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl.MyFooBar += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler&amp;ltMyCustomEventArgs&amp;gt(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl_MyFooBarHandler);&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; oMyControl_MyFooBarHandler(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, MyCustomEventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// whatever your code needs to be, such as&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; message = &lt;span style="color: #cc6633;"&gt;"FOO was specified!"&lt;/span&gt;; &lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (e.IsBarSpecified == &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;)&lt;br /&gt;        message += &lt;span style="color: #cc6633;"&gt;" BAR too!"&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;    MessageBox.Show(message);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Or this, if you want to use an anonymous delegate (note that since I'm utilizing the custom MyCustomEventArgs, I'll need to specify them here, whereas I didn't need any of the parameters in the first example):&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #e8d8b7; font-family: 'Courier New', Courier, Monospace; font-size: 10pt; line-height: 10pt; border-style: none; color: black; overflow: visible; padding: 0px; width: 100%; margin: 0em; direction: ltr; text-align: left;"&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.oMyControl.MyFooBar += &lt;span style="color: #0000ff;"&gt;delegate&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; sender, MyCustomEventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;// whatever your code needs to be, such as&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; message = &lt;span style="color: #cc6633;"&gt;"FOO was specified!"&lt;/span&gt;; &lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (e.IsBarSpecified == &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;)&lt;br /&gt;        message += &lt;span style="color: #cc6633;"&gt;" BAR too!"&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;    MessageBox.Show(message);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-1198088647916366476?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/1198088647916366476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/03/custom-events.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1198088647916366476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1198088647916366476'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/03/custom-events.html' title='Custom Events'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-8072618017181313827</id><published>2010-03-07T14:30:00.001-08:00</published><updated>2010-03-07T14:30:51.374-08:00</updated><title type='text'>Uncommitted Child Table Changes</title><content type='html'>&lt;p&gt;A few months ago, there was a question on the MSDN forums that reminded me of a similar question quite some time ago that I had answered. The issue crops up with parent/child DataTables using Relations. The symptoms of the problem are that your Child table is often left with uncommitted changes, even if you &lt;strong&gt;&lt;u&gt;thought&lt;/u&gt;&lt;/strong&gt; you properly did an .EndEdit() on that Child table. This blog post will explain why that happens and what to do about it.&lt;/p&gt;  &lt;p&gt;OK, so let’s get some sample stuff set up first. &lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// First, let's set the BindingSource using MyRelation&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BindingSource();&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsChild = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BindingSource();&lt;p&gt;&lt;p /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent.DataSource = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MyDataSet;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent.DataMember = &lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsChild.DataSource = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsChild.DataMember = &lt;span style="color: #cc6633"&gt;&amp;quot;MyRelation&amp;quot;&lt;/span&gt;;&lt;p&gt;&lt;p /&gt;&lt;span style="color: #008000"&gt;// now bind a grid and a textbox&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oGrid.DataSource = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtLastName.DataBindings.Add(&lt;span style="color: #cc6633"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsChild, &lt;span style="color: #cc6633"&gt;&amp;quot;description&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;If you make a change in the TextBox (bound to the Child table), and move to other rows in the Grid (the Parent table), maybe even making other changes in the TextBox for each Grid row, then click on a Save button, when you do this.MyDataSet.GetChanges(), you will be missing some of those changes from your Child table. Here’s why: &lt;/p&gt;

&lt;p&gt;1) Data in a DataRow has several different versions, one of which is a “Proposed” version and your changes are still stuck in this Proposed state and the .GetChanges() method only gets those with the “Current” version. See my earlier blog entry for a more in-depth explanation of DataRow versions and one way of handling this issue:&amp;#160; &lt;a title="http://geek-goddess-bonnie.blogspot.com/2009/09/fun-with-datasets.html" href="http://geek-goddess-bonnie.blogspot.com/2009/09/fun-with-datasets.html"&gt;http://geek-goddess-bonnie.blogspot.com/2009/09/fun-with-datasets.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Because you’ve made changes to child records that are related to different parent records, then the bsChild.EndEdit() only commits the Proposed changes for the current relation, even though you've changed other rows with different parents.&lt;/p&gt;

&lt;p&gt;At first, I thought a good solution to this was to create a third BindingSource associated with the entire Child table, having nothing whatsoever to do with the Relationship. That way, when you Save, you could call bsChildTable.EndEdit() rather than bsChild.EndEdit(). Sounds good in theory, but unfortunately, it did *NOT* work.&lt;/p&gt;

&lt;p&gt;So, are we stuck using the CommitProposedChanges() method I created in the above-mentioned earlier blog post? (You *did* read that post I hope).&amp;#160; Well, it will still work just fine. But, because we are using relationships and BindingSources based on those relationships, we can speed it up a bit as follows:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// defining ParentTable simply for clarity of the example&lt;/span&gt;&lt;br /&gt;DataTable ParentTable = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MyDataSet.Tables[&lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;];&lt;p&gt;&lt;p /&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; ParentTable.Rows.Count; i++)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent.Position = i;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsParent.EndEdit();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.bsChild.EndEdit();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;So, all we’re doing is spinning through the Parent table, moving the “record pointer” (setting the .Position property) to each parent row. This then “re-sets” the current relationship with each iteration through the Parent table’s rows so that the bsChild.EndEdit() applies to each successive relation.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-8072618017181313827?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/8072618017181313827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/03/uncommitted-child-table-changes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8072618017181313827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8072618017181313827'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/03/uncommitted-child-table-changes.html' title='Uncommitted Child Table Changes'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-8310497620921724707</id><published>2010-02-28T21:40:00.001-08:00</published><updated>2010-02-28T21:40:44.564-08:00</updated><title type='text'>CheckBox Class Bound to Non-Booleans</title><content type='html'>&lt;p&gt;Well, it’s been awhile since I’ve posted. I have no excuse, other than I’ve been super-busy, but aren’t we all? So … lousy excuse. One of my kids, who calls frequently, always starts out the conversation with “So, what are you doing?” and I always reply “Working”. That invariably gets a response from him of&amp;#160; “How can an un-employed person always be working?!?” Well, just because I’m not getting paid, doesn’t mean that I’m not busy working on the next latest-and-greatest idea to save humanity … or at least make life easier. ;0)&lt;/p&gt;  &lt;p&gt;Anyway, that said, I’m going to post a pretty quick-and-dirty class here, but it addresses an issue I see frequently asked on the forums. As we all know, a CheckBox is typically bound to a boolean value. I mean, it’s either checked or it’s not … true or false. But, sometimes developers&amp;#160; have to deal with legacy data from legacy databases, or maybe just poorly designed databases, where something other than a boolean (or bit in many databases) is used to represent true/false … character strings such as “T”/”F” or “Y”/”N”.&lt;/p&gt;  &lt;p&gt;The key point to making this work, is to handle the Format and Parse events of the Binding. This class can be extended to be able to used with other strings, such as “T”/”F”, but I’ll leave that as an exercise for the reader:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBCheckBoxString : System.Windows.Forms.CheckBox&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; Binding oBinding = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DataBind(System.Data.DataTable Data, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Column)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Checked = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oBinding = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Binding(&lt;span style="color: #cc6633"&gt;&amp;quot;Checked&amp;quot;&lt;/span&gt;, Data, Column);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oBinding.Format += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ConvertEventHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormatHandler);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oBinding.Parse += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ConvertEventHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ParseHandler);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataBindings.Add(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oBinding);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FormatHandler(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ConvertEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.Value.ToString() == &lt;span style="color: #cc6633"&gt;&amp;quot;Y&amp;quot;&lt;/span&gt;)&lt;br /&gt;            e.Value = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            e.Value = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ParseHandler(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ConvertEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;)e.Value == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;br /&gt;            e.Value = &lt;span style="color: #cc6633"&gt;&amp;quot;Y&amp;quot;&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            e.Value = &lt;span style="color: #cc6633"&gt;&amp;quot;N&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Pretty easy, right? The Format event takes the value of the column in your DataTable (“Y”/”N”) and converts it to true/false to be displayed as a checkmark (or empty box). The Parse handler does the opposite. It takes the value of the Checked property (true/false) and converts it to “Y”/”N” to be placed back in the data column.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-8310497620921724707?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/8310497620921724707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/02/checkbox-class-bound-to-non-booleans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8310497620921724707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8310497620921724707'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2010/02/checkbox-class-bound-to-non-booleans.html' title='CheckBox Class Bound to Non-Booleans'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-2265368150443567514</id><published>2009-12-30T09:15:00.001-08:00</published><updated>2009-12-30T09:15:15.373-08:00</updated><title type='text'>Getting Non-Null Data Redux</title><content type='html'>&lt;p&gt;It has been pointed out to me that my &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/11/getting-non-null-data.html" target="_blank"&gt;previous post about this topic&lt;/a&gt; is a bit out-dated. Yes, it is and I did mention in that post that the code I posted was from an old 1.1 class that I never bothered to update when things like extension methods came along in subsequent .NET versions.&lt;/p&gt; &lt;p&gt;Well, I guess I’ve been chastised enough for it, so I’ll post some new code using extension methods. But first, I &lt;strong&gt;&lt;u&gt;do&lt;/u&gt;&lt;/strong&gt; want to say something about extension methods. They are cool, they make some things much easier (as I’ll illustrate at the end of this post) but they can also be over-used and therefore abused (IMHO). When over-using extension methods, it may be very easy to forget that these new methods are not native to .NET, that you (or another developer on your team) has created them. But, I suppose that will be brought home to you when you work on other apps that don’t have the extension method code in them … it just may take you awhile to remember, “Oh yeah, Intellisense isn’t showing this method because it isn’t there natively. Darn!”&lt;/p&gt; &lt;p&gt;One other note about the previously posted code (which I will correct in that post), is that I used code like this:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != DBNull.Value &amp;amp;&amp;amp; Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;When, of course, it should have been the other way around, silly me:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;So, without further ado, here’s the revised version using extension method (and really, all that has to be done is to add “this” to each method signature and I also changed the name of the class):&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Default)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Test;        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;    &lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Default)    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)         &lt;br /&gt;        {            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime)             &lt;br /&gt;            {                &lt;br /&gt;                DateTime TestDT = Convert.ToDateTime(Test);                &lt;br /&gt;                DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;p&gt;&lt;/p&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT == SqlNull)                    &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;            &lt;br /&gt;            }            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;)            &lt;br /&gt;            {                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; YesNo = Convert.ToBoolean(Test);                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (YesNo)                    &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;Yes&amp;quot;&lt;/span&gt;;                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;                    &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;No&amp;quot;&lt;/span&gt;;            &lt;br /&gt;            }                                &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Test.ToString().Trim();        &lt;br /&gt;        }        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;    &lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Default)    &lt;br /&gt;    {        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Convert.ToInt32(Test);        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;    &lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DateTime GetNonNull(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, DateTime Default)    &lt;br /&gt;    {                &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)        &lt;br /&gt;        {            &lt;br /&gt;            DateTime TestDT = Convert.ToDateTime(Test);            &lt;br /&gt;            DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);            &lt;br /&gt;            DateTime NetNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1, 1, 1);                        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT != SqlNull &amp;amp;&amp;amp; TestDT != NetNull)                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; TestDT;            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;        &lt;br /&gt;        }        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;    &lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetNonNullDate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Default)&lt;br /&gt;    {    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)     &lt;br /&gt;        {        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime)         &lt;br /&gt;            {            &lt;br /&gt;                DateTime TestDT = Convert.ToDateTime(Test);            &lt;br /&gt;                DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);                    &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT != SqlNull)                &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; TestDT.ToShortDateString();        &lt;br /&gt;            }                        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;    &lt;br /&gt;        }    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DateTime GetNonNullDate(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test)&lt;br /&gt;    {    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value &amp;amp;&amp;amp; Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime)         &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Convert.ToDateTime(Test);    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;So, now why is this better than the old CommonFunctions class I had? Well, here’s how you had to use the old class:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyInt = CommonFunctions.GetNonNull(MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyColumn&amp;quot;&lt;/span&gt;], 0);&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000"&gt;// -or-&lt;/span&gt;&lt;p&gt;&lt;/p&gt;DateTime MyDatetime = CommonFunctions.GetNonNullDate(MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyDateColumn&amp;quot;&lt;/span&gt;])&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;And here’s the extension method way of doing this, a bit cleaner:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyInt = MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyColumn&amp;quot;&lt;/span&gt;].GetNonNull(0);&lt;p&gt;&lt;/p&gt;&lt;span style="color: #008000"&gt;// -or-&lt;/span&gt;&lt;p&gt;&lt;/p&gt;DateTime MyDatetime = MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyDateColumn&amp;quot;&lt;/span&gt;].GetNonNullDate();&lt;/pre&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-2265368150443567514?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/2265368150443567514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/12/getting-non-null-data-redux.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2265368150443567514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2265368150443567514'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/12/getting-non-null-data-redux.html' title='Getting Non-Null Data Redux'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7242393722051209641</id><published>2009-12-20T15:53:00.001-08:00</published><updated>2009-12-20T15:53:32.638-08:00</updated><title type='text'>DefaultValue for Properties</title><content type='html'>&lt;p&gt;When in the Designer for a Form, everyone knows that you can go to the Properties window and change a property on the form or a control. You most likely also know that you can then right-click on any changed property, and choose &amp;quot;Reset&amp;quot; to set it back to its Default Value.&lt;/p&gt; &lt;p&gt; What code do you need in your own controls to get that to work? You need code in two places: in the Constructor to set the value to begin with, and a [DefaultValue] attribute for the Property itself:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyTextBox : TextBox&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_MyProperty;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyTextBox&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_MyProperty = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #008000"&gt;// As an additional bonus, I'm showing you two ways to do color&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BackColor = System.Drawing.Color.FromArgb(90, 100, 240);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForeColor = System.Drawing.Color.Firebrick; ;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    [DefaultValue(&lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; MyProperty&lt;br /&gt;    {&lt;br /&gt;        get {&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_MyProperty;}&lt;br /&gt;        set {&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_MyProperty = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;}&lt;br /&gt;    }&lt;br /&gt;    [DefaultValue(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(System.Drawing.Color), &lt;span style="color: #cc6633"&gt;&amp;quot;90,100,240&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; System.Drawing.Color BackColor&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.BackColor;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.BackColor = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    [DefaultValue(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(System.Drawing.Color), &lt;span style="color: #cc6633"&gt;&amp;quot;Firebrick&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; System.Drawing.Color ForeColor&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ForeColor;&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ForeColor = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Some properties aren't virtual and can't be overridden. For those properties, you can use &amp;quot;new&amp;quot; instead of &amp;quot;override&amp;quot;.&lt;/p&gt;
&lt;p&gt;The [DefaultValue] attribute serves two purposes: &lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;It allows the property to be easily Reset to it's Default Value from the Property Sheet.&lt;/li&gt;
  &lt;li&gt;It prevents the code that sets the default value from actually showing up in the InitializeComponent() method.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That second point is pretty important. Let me illustrate why. Say that you've &lt;strong&gt;&lt;u&gt;not&lt;/u&gt;&lt;/strong&gt; used the [DefaultValue] attribute in your TextBox, but simply set the value of the BackColor and ForeColor properties in your MyTextBox constructor, like this:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyTextBox : TextBox&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyTextBox()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BackColor = Color.DarkGreen;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForeColor = Color.Firebrick;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;When you drop this TextBox onto a Form, the BackColor and ForeColor will be explicitly set in the code&amp;#160; generated in the&amp;#160; InitializeComponent() method of the Form (IOW, you’ll have the code to set BackColor and ForeColor for every TextBox you drop on your design surface). Consequently, if you later decide to change the color in your MyTextBox class, you have to revisit every single Form that you ever dropped a MyTextBox on, to change it to the new default value. &lt;strong&gt;&lt;u&gt;Not good!&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Conversely, let's look at the opposite scenario where you &lt;strong&gt;&lt;u&gt;do&lt;/u&gt;&lt;/strong&gt; include a property with a [DefaultValue] attribute, but you &lt;strong&gt;&lt;u&gt;don't&lt;/u&gt;&lt;/strong&gt; initialize that in the constructor. So, your class looks like this:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyTextBox : TextBox&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// bad code! Do not try this at home! ;0)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyTextBox()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    [DefaultValue(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(System.Drawing.Color), &lt;span style="color: #cc6633"&gt;&amp;quot;DarkGreen&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; System.Drawing.Color BackColor&lt;br /&gt;    {&lt;br /&gt;        get {&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.BackColor;}&lt;br /&gt;        set {&lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.BackColor = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;}&lt;br /&gt;    }&lt;br /&gt;    [DefaultValue(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(System.Drawing.Color), &lt;span style="color: #cc6633"&gt;&amp;quot;Firebrick&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; System.Drawing.Color ForeColor&lt;br /&gt;    {&lt;br /&gt;        get {&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ForeColor;}&lt;br /&gt;        set {&lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ForeColor = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;}&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;When you drop MyTextBox on a Form now, it will default to a color of SystemColors.Control for the BackColor property and SystemColors.WindowText for the ForeColor property, and the IDE will generate the code in the InitializeComponent() method of the Form where you dropped MyTextBox onto, &lt;strong&gt;&lt;u&gt;unless&lt;/u&gt;&lt;/strong&gt; you go to the Property Sheet, right-click the BackColor and choose &amp;quot;Reset&amp;quot; (and likewise for ForeColor). Once you do this, the correct color appears for the TextBox in the Designer, the IDE removes the setting of the BackColor and ForeColor properties in the InitializeComponent() method and all looks fine ... until you decide to change the default to something else in your MyTextBox class ... since your TextBox doesn't initialize its BackColor and ForeColor properties in its constructor, the Form goes back to displaying SystemColors.Control and SystemColors.WindowText (even though it's not hard-coded in the InitializeComponent() method).&amp;#160; Again, this is &lt;strong&gt;&lt;u&gt;not good!&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Suffice it to say that you simply must do both -- initialize it in the constructor and specify the [DefaultValue] attribute. Just something that you're going to have to remember to do!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7242393722051209641?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7242393722051209641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/12/defaultvalue-for-properties.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7242393722051209641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7242393722051209641'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/12/defaultvalue-for-properties.html' title='DefaultValue for Properties'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-5744578289116369406</id><published>2009-11-30T16:57:00.001-08:00</published><updated>2009-11-30T16:57:10.356-08:00</updated><title type='text'>Hooking Into the Form's Events, from Form Controls</title><content type='html'>&lt;p&gt;Have you ever had the need to have a Control on your Form hook into some of the Form’s events? For example, say you have a Control on your Form that needs to do something extra when the Form Loads or the Closing event is triggered.&lt;/p&gt; &lt;p&gt;Let's use an example to illustrate how we might accomplish this. Let's use the ListView as an example. First, we'll sub-class the ListView Control. As you can see, we override the OnParentChanged event in the ListView sub-class.&lt;/p&gt; &lt;p&gt;We’ll utilize the TopLevelControl (not the Parent). If the TopLevelControl is null then we hookup event handlers backwards through the control hierarchy as each control is parented. When we finally get to a TopLevelControl for a Form type we hookup the load/closing event handlers.&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyListView : System.Windows.Forms.ListView&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Form FormParent = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyListView()&lt;br /&gt;   {&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnParentChanged(EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnParentChanged(e);&lt;br /&gt;            &lt;br /&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DesignMode == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TopLevelControl != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TopLevelControl &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; Form)&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent = (Form)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.TopLevelControl;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.EstablishParentEvents();&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;         {&lt;br /&gt;            Control LastParent = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(LastParent != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;               LastParent.ParentChanged += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(LastParent_ParentChanged);&lt;br /&gt;               LastParent = LastParent.Parent;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EstablishParentEvents()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent.Closing += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CancelEventHandler(MyListView_Closing);&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent.Load += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(MyListView_Load);&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MyListView_Closing(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, CancelEventArgs e)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #008000"&gt;// put your extra code here&lt;/span&gt;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent.Closing -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CancelEventHandler(MyListView_Closing);&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent.Load -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(MyListView_Load);&lt;br /&gt;      }&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MyListView_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #008000"&gt;// put your extra code here&lt;/span&gt;&lt;br /&gt;   }&lt;p&gt;&lt;/p&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LastParent_ParentChanged(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;      Control Source = (Control)sender;&lt;p&gt;&lt;/p&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Source.TopLevelControl != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Source.TopLevelControl &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; Form)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FormParent = (Form)Source.TopLevelControl;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.EstablishParentEvents();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
Thanks to Neil Tonkin in Message #1084683 from the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-5744578289116369406?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/5744578289116369406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/hooking-into-form-events-from-form.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5744578289116369406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5744578289116369406'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/hooking-into-form-events-from-form.html' title='Hooking Into the Form&amp;#39;s Events, from Form Controls'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-3373969793704318145</id><published>2009-11-20T21:51:00.001-08:00</published><updated>2009-11-20T21:51:45.379-08:00</updated><title type='text'>Reflection Class Redux</title><content type='html'>&lt;p&gt;I’m sorry to say that there was a bug of sorts in the MyReflectionClass posted in my blog entry back in September (&lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/reflection-in-net.html"&gt;Reflection In .NET&lt;/a&gt;). It was in the LoadAssembly() method and it’s been corrected in the original post. &lt;/p&gt;  &lt;p&gt;One of the comments in that original post (the comment has been modified now) was that you might need to include the full path of the Assembly as part of the Assembly name. Well,&amp;#160; we really &lt;strong&gt;do&lt;/strong&gt; have to take into account a path to the Assembly, but not as part of its name, which was the implication of my original comment.&amp;#160; &lt;/p&gt;  &lt;p&gt;Sorry for any confusion or pulling of hair that this has caused. =0(&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-3373969793704318145?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/3373969793704318145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/reflection-class-redux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3373969793704318145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3373969793704318145'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/reflection-class-redux.html' title='Reflection Class Redux'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7201489771990226472</id><published>2009-11-19T16:34:00.001-08:00</published><updated>2009-11-19T16:34:02.334-08:00</updated><title type='text'>Dynamic Menu Items</title><content type='html'>&lt;p&gt;There was a question recently on the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt; about dynamically adding MenuItems to a Form. The data for these dynamically added Items can be obtained from anywhere, like from your database. This fits in quite nicely with the first substantial post I wrote in this blog back in September, &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/reflection-in-net.html"&gt;Reflection in .NET&lt;/a&gt;, because you can use these dynamically added Items to launch new DLLs that you might create (for example, a custom form for one of your customers), via Reflection, without having to recompile and re-distribute your entire application. Just supply the newly-created DLL. At my last company, we used DevExpress SideBars and incorporated this dynamic functionality that way.&lt;/p&gt; &lt;p&gt;So, without further ado, here’s the first thing: the code you need to dynamically add the menu items. Note that this creates different sub-classes of MenuItems, depending on your data:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestMenuAddItemsDynamically()&lt;br /&gt;{&lt;br /&gt;    MenuItem item;  &lt;span style="color: #008000"&gt;// This is so you can use MenuItem sub-classes&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (DataRow row &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oData.Rows)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(row[&lt;span style="color: #cc6633"&gt;&amp;quot;assembly&amp;quot;&lt;/span&gt;].ToString()) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            item = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; LaunchMenuItem(row[&lt;span style="color: #cc6633"&gt;&amp;quot;description&amp;quot;&lt;/span&gt;].ToString(), row[&lt;span style="color: #cc6633"&gt;&amp;quot;assembly&amp;quot;&lt;/span&gt;].ToString(), row[&lt;span style="color: #cc6633"&gt;&amp;quot;class&amp;quot;&lt;/span&gt;].ToString());&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddMenuItem(&lt;span style="color: #cc6633"&gt;&amp;quot;Custom Forms&amp;quot;&lt;/span&gt;, item);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(row[&lt;span style="color: #cc6633"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;].ToString()) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            item = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FavoritesMenuItem(row[&lt;span style="color: #cc6633"&gt;&amp;quot;description&amp;quot;&lt;/span&gt;].ToString(), row[&lt;span style="color: #cc6633"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;].ToString());&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddMenuItem(&lt;span style="color: #cc6633"&gt;&amp;quot;Favorites&amp;quot;&lt;/span&gt;, item);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            item = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DefaultMenuItem(row[&lt;span style="color: #cc6633"&gt;&amp;quot;description&amp;quot;&lt;/span&gt;].ToString());&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddMenuItem(&lt;span style="color: #cc6633"&gt;&amp;quot;Dynamic Menu&amp;quot;&lt;/span&gt;, item);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Next, I’ll show you the LaunchMenuItem class, since it is what this post is focusing on. &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// Used to launch a DLL by Reflection&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LaunchMenuItem : MenuItem&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; AssemblyName;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ClassName;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; LaunchMenuItem(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; assemblyName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; className)&lt;br /&gt;        : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(text)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Click += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.EventHandler(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClickHandler);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AssemblyName = assemblyName;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClassName = className;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClickHandler(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        MyReflectionClass oReflect = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyReflectionClass(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AssemblyName, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClassName);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000"&gt;// In it's simplest usage, I will assume that the class I am instantiating is a Form&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Expanding on this concept is left as an exercise for the reader.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// I've also left out error checking for the instantiated object&lt;/span&gt;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; message = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;        Form oForm = oReflect.InstantiateClass(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; message) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Form;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (oForm == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            MessageBox.Show(message);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            oForm.Show();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Note that the above class uses the MyReflectionClass from my previous post on the subject, &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/reflection-in-net.html"&gt;Reflection In .NET&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The other custom MenuItem classes would contain other things to do in their Click event handlers, such as browsing to a URL link inside a BrowserControl on your Form (for the FavoritesMenuItem class). I’m not including that code in this example … I leave it as an exercise for the reader.&lt;/p&gt;
&lt;p&gt;There’s one more method to show, and that’s a common method that will add any MenuItem to the Form’s Menu. Notice that it does things like check to see if the top menu item already exists (“Custom Forms”, “Favorites” and “Dynamic Menu” in the above example). It adds it if it doesn’t, and then adds the new MenuItems under it.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// Generic method for adding to any Menu&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddMenuItem(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; name, MenuItem item)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; lookForName = name.Replace(&lt;span style="color: #cc6633"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;, &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Find top-level menu item&lt;/span&gt;&lt;br /&gt;    MenuItem addTo = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Menu.MenuItems.Count; i++)&lt;br /&gt;    {&lt;br /&gt;        MenuItem topLevel = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Menu.MenuItems[i];&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Compare(topLevel.Text.Replace(&lt;span style="color: #cc6633"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;, &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;), lookForName, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) == 0)&lt;br /&gt;        {&lt;br /&gt;            addTo = topLevel;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Was a top-level menu item found?&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (addTo == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        addTo = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MenuItem(name);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Menu.MenuItems.Add(addTo);&lt;br /&gt;        addTo.Index = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Menu.MenuItems.Count - 2;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    addTo.MenuItems.Add(item);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;That about wraps it up. I hope this has given my readers lots of ideas to go forth and try out some cool dynamic stuff.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7201489771990226472?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7201489771990226472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/dynamic-menu-items.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7201489771990226472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7201489771990226472'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/dynamic-menu-items.html' title='Dynamic Menu Items'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-6620043049694521577</id><published>2009-11-15T22:00:00.001-08:00</published><updated>2009-11-19T16:39:18.235-08:00</updated><title type='text'>Setting Focus to a Control at Form Load</title><content type='html'>&lt;p&gt;I used to write a “.Net Tips and Tricks” column for an online magazine associated with a forum called the&amp;#160; &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;. The magazine has been known by several names, the Universal Thread Magazine, Level Extreme .NET Magazine and simply the UT Mag. Unfortunately, after being in “publication” since 2001, the last issue was in April of this year and it doesn’t look like it will be published anymore.&lt;/p&gt; &lt;p&gt;So, if no one minds, I think it’s time to start including a few of the Tips from my columns over the years. The format of my column was to garner tidbits of wisdom from other people’s posts on the &lt;a href="http://www.universalthread.com/"&gt;UT&lt;/a&gt;, re-work them into a good format for a Tip, and credit the people who wrote the post (sometime it was even from a post that I wrote).&lt;/p&gt; &lt;p&gt;So, let’s start out with this --- how about a simple WinForms tip. Nothing earth-shattering here, but worth mentioning.&lt;/p&gt; &lt;p&gt;Normally, the Focus() method of a control is used to move the focus to that control: &lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MyButton_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Move the Focus elsewhere&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MySpecialTextBox.Focus();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;This works at any time, &lt;strong&gt;except&lt;/strong&gt; during Form/Control Load. Then, you simply have to set the ActiveControl: &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MyForm_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Start the Form with the Focus on a certain control&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ActiveControl = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MySpecialTextBox;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Thanks to Kevin McNeish in Message #1080245 on the &lt;a href="http://www.universalthread.com/" target="_blank"&gt;Universal Thread&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-6620043049694521577?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/6620043049694521577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/setting-focus-to-control-at-form-load.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6620043049694521577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/6620043049694521577'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/setting-focus-to-control-at-form-load.html' title='Setting Focus to a Control at Form Load'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-1277887489143176778</id><published>2009-11-05T15:49:00.001-08:00</published><updated>2009-12-30T09:29:19.882-08:00</updated><title type='text'>Getting Non-Null Data</title><content type='html'>&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: See &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/12/getting-non-null-data-redux.html" target="_blank"&gt;my new post on this topic&lt;/a&gt;. (I also corrected code in this current post, where I changed to test for null before testing for DBNull.Value ... it was an oversight on my part. Sorry, hope it didn't cause anyone problems).&lt;/p&gt; &lt;p&gt;I see questions along these lines all the time:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;//I'm doing this:&lt;/span&gt;&lt;p /&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; CustID = (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)dsCustomer.Tables[&lt;span style="color: #cc6633"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;CustID&amp;quot;&lt;/span&gt;];&lt;p /&gt;&lt;span style="color: #008000"&gt;// It throws an exception because CustID is DBNull in the data. &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// How do I handle this?&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;I have a CommonFunctions class that I use for things such as a GetNonNull( ) method (it's an old class, dating back to the 1.1 days, but it still works fine and so I have never updated it for 2.0, haven't really looked to see if it's even necessary).&amp;#160; This will work for any type of object, not just data in a DataSet, but is seems that DataSet access is&amp;#160; the commonly asked question.&lt;/p&gt;
&lt;p&gt;This is implemented with many overloads, but here's an example of just a few:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CommonFunctions&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Default)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Test;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Default)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value) &lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime) &lt;br /&gt;            {&lt;br /&gt;                DateTime TestDT = Convert.ToDateTime(Test);&lt;br /&gt;                DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;br /&gt;            &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT == SqlNull)&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; YesNo = Convert.ToBoolean(Test);&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (YesNo)&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;Yes&amp;quot;&lt;/span&gt;;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #cc6633"&gt;&amp;quot;No&amp;quot;&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;                    &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Test.ToString().Trim();&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; GetNonNull(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Default)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Convert.ToInt32(Test);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DateTime GetNonNull(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, DateTime Default)&lt;br /&gt;    {&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value)&lt;br /&gt;        {&lt;br /&gt;            DateTime TestDT = Convert.ToDateTime(Test);&lt;br /&gt;            DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;br /&gt;            DateTime NetNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1, 1, 1);&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT != SqlNull &amp;amp;&amp;amp; TestDT != NetNull)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; TestDT;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;These are just a sample of the overloads I use. I have a few more such as for bool, decimal, long and even a few differently named methods specifically for Dates, such as these next two: &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetNonNullDate(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Default)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value) &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime) &lt;br /&gt;        {&lt;br /&gt;            DateTime TestDT = Convert.ToDateTime(Test);&lt;br /&gt;            DateTime SqlNull = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;br /&gt;        &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(TestDT != SqlNull)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; TestDT.ToShortDateString();&lt;br /&gt;        }&lt;br /&gt;                &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Default;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DateTime GetNonNullDate(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Test)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Test != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Test != DBNull.Value &amp;amp;&amp;amp; Test &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DateTime) &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Convert.ToDateTime(Test);&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1900, 1, 1);&lt;br /&gt;}&lt;p /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Anyway, you get the point. Note that these are static methods, so no instantiation of the CommonFunctions class is necessary.To use them, you would simply have something like this: &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyInt = CommonFunctions.GetNonNull(MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyColumn&amp;quot;&lt;/span&gt;], 0);&lt;p /&gt;&lt;span style="color: #008000"&gt;// -or-&lt;/span&gt;&lt;p /&gt;DateTime MyDatetime = CommonFunctions.GetNonNullDate(MyDataSet.Tables[0].Rows[0][&lt;span style="color: #cc6633"&gt;&amp;quot;MyDateColumn&amp;quot;&lt;/span&gt;])&lt;br /&gt;&lt;/pre&gt;
  &lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-1277887489143176778?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/1277887489143176778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/getting-non-null-data.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1277887489143176778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1277887489143176778'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/11/getting-non-null-data.html' title='Getting Non-Null Data'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-169534116174338655</id><published>2009-10-27T12:59:00.001-07:00</published><updated>2009-11-28T14:16:53.895-08:00</updated><title type='text'>DataAccess - Part III</title><content type='html'>&lt;p&gt;If you’ve already read my previous posts about DataAccess (&lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html"&gt;Part I&lt;/a&gt; and &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html"&gt;Part II&lt;/a&gt;), you’ll notice that I said nothing about writing this in 3 parts. However, I realized that I left out another, better methodology for writing DataAccess classes. So, I thought I better address that pronto.&lt;/p&gt; &lt;p&gt;This better methodology involves classes using anonymous delegates. These classes can live directly in your DataAccess base class, or you can put them in your Business base class (so that your Business classes can effectively manage multiple “transactions” involving multiple DataAccess classses, rather than having it all be done at the DataAccess layer). To simplify matters, I will show this methodology only in the DataAccess base class and leave it as an exercise to the reader to extend the concepts to the Business layer. &lt;/p&gt; &lt;p&gt;What follows is a very simplified, but workable, version … I’ve left out some of the “nice-to-have” features that don’t affect the basic usability of the class (such as timeouts &amp;amp; transactions). Some of my method names might seem a bit “crude”, but I didn’t want it to resemble actual code in use. You know, copyright and all that. The point is to get the concepts across and let you expand on those concepts on your own. &lt;/p&gt; &lt;p&gt;So, first let’s look at the few key points. Here are the basic additions to the DataAccess class I showed in &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html"&gt;Part II&lt;/a&gt; that make this whole thing work:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TheMethod();&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; TheMethod m_DoIt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; TheMethod m_UndoIt;&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TheMethod DoIt&lt;br /&gt;{ &lt;br /&gt;    set { m_DoIt = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; } &lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TheMethod UndoIt&lt;br /&gt;{&lt;br /&gt;    set { m_UndoIt = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Start()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; success = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Enter the retry loop&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (!success)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// Commented out because I haven't included transactions in my example&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;//this.BeginTransaction();&lt;/span&gt;&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_DoIt();&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #008000"&gt;// Here is where you'd commit your database transactions&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;//this.CommitTransaction();&lt;/span&gt;&lt;p&gt;&lt;/p&gt;            success = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.RetryRequested(e) &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.attempt &amp;lt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.maxRetries)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Try to undo any changes before we retry&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// If we can't, just abort&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.UndoChanges())&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForceCleanup();&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.attempt++;&lt;p&gt;&lt;/p&gt;                &lt;span style="color: #008000"&gt;// Might want to sleep for random period&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;//System.Random rand = new System.Random();&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;//System.Threading.Thread.Sleep(rand.Next(MinSleepTime, MaxSleepTime));&lt;/span&gt;&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Max number of retries exceeded or an unrecoverable error &lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// - fail and return error message&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForceCleanup();&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (success);&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; UndoChanges()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_UndoIt != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_UndoIt();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;I’ll explain how it works in a minute, but first let’s see the code you would use in your sub-classes to utilize the delegates:&lt;/p&gt;
  &lt;div&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CustomerDataSet GetCustomer(&lt;span style="color: #0000ff"&gt;long&lt;/span&gt; customerkey)&lt;br /&gt;{&lt;br /&gt;    CustomerDataSet ds = &lt;span style="color: #0000ff"&gt;null;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DoIt = &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;()&lt;br /&gt;    {&lt;br /&gt;        ds = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerDataSet();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClearParameters();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddParms(&lt;span style="color: #cc6633"&gt;&amp;quot;CustomerKey&amp;quot;&lt;/span&gt;, customerkey); &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FillData(ds, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_CustomerGet&amp;quot;&lt;/span&gt;);&lt;br /&gt;    };&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Start();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ds;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SaveCustomer(CustomerDataSet dsChanged, CustomerDataSet dsDeleted)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DoIt = &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// you'd also want to wrap all this in a transaction, I just haven't&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// shown transactions in this example&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SaveTable(dsChanged.Customer, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_CustomersPut&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SaveTable(dsChanged.Orders, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_OrdersPut&amp;quot;&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dsDeleted != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SaveTable(dsDeleted.Orders, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_OrdersDelete&amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SaveTable(dsDeleted.Customer, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_CustomerDelete&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.UndoIt = &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;()&lt;br /&gt;    {&lt;br /&gt;        dsChanged.RejectChanges();&lt;br /&gt;        dsDeleted.RejectChanges();&lt;br /&gt;    };&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Start();&lt;br /&gt;}&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, I obviously have not shown all the methods in the class (I’ll post the entire simplified version of the class at the end of this post). But, let me explain how this works. Basically, you set up two anonymous delegates, DoIt and UndoIt, then run the Start() method which in turn runs the code defined in the delegates. The beauty of it all is that the Start() method contains the only try/catch stuff you need and therefore handles any and all exceptions. It completely does away with the necessity of writing try/catch blocks in all your DataAccess methods, and having to have the developer remember to check return values and or ErrorMessages from every method call.&lt;/p&gt;
&lt;p&gt;In the Start() method, the DoIt delegate code runs first. If there are any exceptions thrown, it checks to see if we want to Retry the operation. If so, first we run the UndoIt delegate code, if any exists, and then run through the loop and try again. Note that the GetCustomer() method doesn’t have any UndoIt code, whereas the SaveCustomer() method does. This is because the dsChanged or the dsDeleted DataSets could possibly be changed in the process of attemping to Save, and thus we want to put them back to their original state before attempting the Save again. This isn’t an issue in the GetCustomer() method. &lt;/p&gt;
&lt;p&gt;Now, as I mentioned, this greatly simplifies the original DataAccess class that I previously posted (no more try/catch stuff needed), so I’ll post the entire class as it now stands:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBDataAccess&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations associated with the &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; approach&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TheMethod();&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; TheMethod m_DoIt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; TheMethod m_UndoIt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TheMethod DoIt&lt;br /&gt;    { &lt;br /&gt;        set { m_DoIt = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; } &lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TheMethod UndoIt&lt;br /&gt;    {&lt;br /&gt;        set { m_UndoIt = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// you can make these into properties, or make them protected&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// so the defaults can be changed&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; maxRetries = 3;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; attempt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;/p&gt;&lt;p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations from the original DataAccess &lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbConnection oConnection;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbCommand oCommand;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbDataAdapter oAdapter;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDataParameterCollection oParms;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ConnectionString = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ErrorMessage = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Tweak, if necessary, for other database servers (Oracle)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; AtSign = &lt;span style="color: #cc6633"&gt;&amp;quot;@&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; DeadlockRollbackError = 1205; &lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Constructor/Destructor&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBDataAccess()&lt;br /&gt;    {&lt;br /&gt;        BBConnection o = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BBConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection = o.GetConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConnectionString = o.ConnectionString;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbCommand();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oAdapter = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbDataAdapter(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Connection = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandType = CommandType.StoredProcedure;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Tweak, if necessary, for other database servers (Oracle)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; AtSign = &lt;span style="color: #cc6633"&gt;&amp;quot;@&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; DeadlockRollbackError = 1205; &lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Constructor/Destructor&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBDataAccess()&lt;br /&gt;    {&lt;br /&gt;        BBConnection o = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BBConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection = o.GetConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConnectionString = o.ConnectionString;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbCommand();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oAdapter = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbDataAdapter(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Connection = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandType = CommandType.StoredProcedure;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Methods associated with the &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; approach&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Start()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; success = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000"&gt;// Enter the retry loop&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (!success)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Start the transaction and execute the methods. Any failures from here&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// to the final commit may result in an exception being thrown and caught which&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// may lead to a retry or an abort depending on the type of error&lt;/span&gt;&lt;p&gt;&lt;/p&gt;                &lt;span style="color: #008000"&gt;// Here is where you would start your database transactions&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// It's commented out because I haven't included it in my example&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;//this.BeginTransaction();&lt;/span&gt;&lt;p&gt;&lt;/p&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_DoIt();&lt;p&gt;&lt;/p&gt;                &lt;span style="color: #008000"&gt;// Here is where you'd commit your database transactions&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;//this.CommitTransaction();&lt;/span&gt;&lt;p&gt;&lt;/p&gt;                success = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #008000"&gt;// Typically we'll want a Retry if the database error was the&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #008000"&gt;// result of a deadlock, but you can Retry for any reason you wish.&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.RetryRequested(e) &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.attempt &amp;lt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.maxRetries)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #008000"&gt;// Try to undo any changes before we retry&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #008000"&gt;// If we can't, just abort&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.UndoChanges())&lt;br /&gt;                    {&lt;br /&gt;                        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;                        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForceCleanup();&lt;br /&gt;                        &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                    }&lt;br /&gt;                    &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.attempt++;&lt;p&gt;&lt;/p&gt;                    &lt;span style="color: #008000"&gt;// Might want to sleep for random period&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #008000"&gt;//System.Random rand = new System.Random();&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #008000"&gt;//System.Threading.Thread.Sleep(rand.Next(MinSleepTime, MaxSleepTime));&lt;/span&gt;&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #008000"&gt;// Max number of retries exceeded or an unrecoverable error &lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #008000"&gt;// - fail and return error message&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForceCleanup();&lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (success);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; RetryRequested(Exception e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; retryRequested = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; BBRetryException) retryRequested = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (e.InnerException != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !retryRequested)&lt;br /&gt;        {&lt;br /&gt;            e = e.InnerException;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; BBRetryException) retryRequested = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; retryRequested;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Try to undo any changes to the operation parameters so that we can retry &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// If the undo fails, the operation is aborted instead&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; UndoChanges()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_UndoIt != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_UndoIt();&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// You can handle error message differently if you wish&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// For this example, I simply set up a public ErrorMessage string&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// that will be an empty string if there were no errors.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddToErrorMessage(Exception e)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e.Message);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.InnerException != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e.InnerException.Message);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddToErrorMessage(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; msg)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage += msg + &lt;span style="color: #cc6633"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Force abort the transaction and cleanup the database connection without raising exceptions&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Any problems are still logged to the error messages list. Used when cleaning up during&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// exception processing where we already know there may be some problem with the database&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// connection&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ForceCleanup()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// commented because I haven't included Transactions in my example&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;//this.RollbackTransaction();&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CloseConnection();&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddToErrorMessage(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Get/Use IDb Interface Objects&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbCommand GetIDbCommand()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbDataAdapter GetIDbDataAdapter(IDbCommand command)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter((SqlCommand)command);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbDataParameter GetIDbDataParameter(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlParameter(ParmName, ParmValue);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DeriveParameters(IDbCommand command)&lt;br /&gt;    {&lt;br /&gt;        SqlCommandBuilder.DeriveParameters((SqlCommand)command);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Parameter Methods&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Then there are the various protected methods for adding and setting Parameters, filling a DataSet, etc.    &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// It's these various methods that get used in the classes that are sub-classed from this &amp;quot;base&amp;quot; class.    &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Here's just a few of them:    &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClearParameters()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.Clear();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddParms(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ParmName.StartsWith(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;            ParmName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign + ParmName;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ParmValue != DBNull.Value)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.Add(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbDataParameter(ParmName, ParmValue));&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddParms(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue, ParameterDirection direction)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddParms(ParmName, ParmValue);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetParmDirection(ParmName, direction);&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetParmDirection(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, ParameterDirection direction)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ParmName.StartsWith(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;            ParmName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign + ParmName;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.IndexOf(ParmName) &amp;gt; -1)&lt;br /&gt;            ((IDbDataParameter)&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters[ParmName]).Direction = direction;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetAllParameters(DataRow Row)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClearParameters();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; Row.Table.Columns.Count; i++)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddParms(Row.Table.Columns[i].ColumnName, Row[i]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Database Methods, &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; the IDb &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; members&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FillData(DataSet ds, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; StoredProcName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandText = StoredProcName;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oAdapter.Fill(ds);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// In order to reduce programmer error and to mimic the native functionality of the&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// DataAdapter.Fill() command, we will open a connection if it has not already &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// been opened, Execute the Command and then leave it in the state that it was in&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// prior to that (close it if needed or leave it open).&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;StoredProcName&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ExecuteCommand(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; StoredProcName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsAlreadyOpen = (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection.State == ConnectionState.Open);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.OpenConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandText = StoredProcName;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #008000"&gt;// &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; &lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.ExecuteNonQuery(); &lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (SqlException ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// Check if the sql exception is because of a deadlock rollback&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;// If so we can attempt a retry&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ex.Number == DeadlockRollbackError)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BBRetryException(&lt;span style="color: #cc6633"&gt;&amp;quot;Deadlock&amp;quot;&lt;/span&gt;, ex);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; ex;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; ex;&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (IsAlreadyOpen == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CloseConnection();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SaveTable(DataTable Table, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SaveProc)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// save each row&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (DataRow row &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Table.Rows)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetAllParameters(row);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ExecuteCommand(SaveProc);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OpenConnection()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection.State != ConnectionState.Open)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection.Open();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CloseConnection()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection.State != ConnectionState.Closed &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Transaction == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection.Close();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBRetryException : Exception&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBRetryException() { }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBRetryException(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; error) : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(error) { }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBRetryException(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; error, Exception e) : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(error, e) { }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-169534116174338655?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/169534116174338655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/169534116174338655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/169534116174338655'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html' title='DataAccess - Part III'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-3536687394357182072</id><published>2009-10-17T15:43:00.001-07:00</published><updated>2009-10-17T15:43:26.146-07:00</updated><title type='text'>Why and How to Sub-class Base Classes</title><content type='html'>&lt;p&gt;One of the “basic rules of programming” that I always live by (and I’m not alone), is that one should &lt;strong&gt;always&lt;/strong&gt; sub-class many of the native base class controls.&amp;#160; This is one of the first things you should do before undertaking any serious development, in any language. There are always little quirks in behavior in some of the base class controls&amp;#160; that you want to get around for every instance of an object.&lt;/p&gt; &lt;p&gt;Say, as an example, that you've developed a few forms for your application. You've used the base class controls. At some point, you find something's not&amp;#160; quite acting right and you want to change that behavior or you may just want to add something (some properties or something) to every ComboBox, for example, that you use. Now, since you used the base class controls to begin with ... guess what? You've outta luck!! You've got a lot of work ahead of you to change all those. Whereas, if you had sub-classed all the controls first (even if you haven't as yet put code in those sub-classes) and used your &lt;strong&gt;sub-classed&lt;/strong&gt; controls on your forms, then you'll have no extra work to do when you decide that you need to make changes to your sub-classed control (and yes, even the form should be sub-classed).&lt;/p&gt; &lt;p&gt;Basically, you'll want a class library that contains your sub-classed UI controls, like textbox, button, etc. Something like this:&lt;/p&gt;&lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Drawing;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; MyCompany.MyFramework.WinUI.MyClasses&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyComboBox : System.Windows.Forms.ComboBox&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyTextBox : System.Windows.Forms.TextBox&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyButton : System.Windows.Forms.Button&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// code here&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;That's it. These controls can't be sub-classed visually, but as you can see, it's easy enough to do it in code. I have all the basic controls sub-classed in one class library file. Once they're added to the ToolBox, then can be dragged onto any design surface in the IDE.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-3536687394357182072?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/3536687394357182072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/why-and-how-to-sub-class-base-classes.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3536687394357182072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3536687394357182072'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/why-and-how-to-sub-class-base-classes.html' title='Why and How to Sub-class Base Classes'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-8151957243602165537</id><published>2009-10-11T14:14:00.001-07:00</published><updated>2009-10-11T14:14:38.478-07:00</updated><title type='text'>Dealing with Carriage Returns in Web Service Methods</title><content type='html'>&lt;p&gt;When returning data from a database through a Web Service (as a DataSet, or as an XML representation of the data in the DataSet), you may have issues with new lines (carriage return/line feed) in your string data.&amp;#160; &lt;/p&gt; &lt;p&gt;I use a SQL Server database. The &amp;quot;new line&amp;quot; data must be stored in the database like this: &amp;quot;\r\n&amp;quot;. But, when passing this through a web service, it must be passed like this: &amp;quot;&amp;amp;#13&amp;quot;. Consequently, to address this discrepancy in format, I use two methods in my Web Service base class: a ConvertCarriageReturnForGets() method and a ConvertCarriageReturnForSaves() method.&lt;/p&gt;&lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;[WebService(Namespace = &lt;span style="color: #cc6633"&gt;&amp;quot;http://mycompany.com/&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBWebServices : System.Web.Services.WebService&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CRLF    = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;amp;#13;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; NewLine = &lt;span style="color: #cc6633"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Convert CarriageReturn Methods&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Converts CarriageReturn/LineFeed characters so they are passed correctly through the Web Service&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;dt&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;ColumnName&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ConvertCarriageReturnForGets(DataTable dt, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ColumnName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dt.Columns.Contains(ColumnName))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; dt.Rows.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dt.Rows[i][ColumnName] != DBNull.Value)&lt;br /&gt;                    dt.Rows[i][ColumnName] = dt.Rows[i][ColumnName].ToString().Replace(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewLine, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CRLF);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// Converts CarriageReturn/LineFeed characters so they are correctly saved to the database&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;dt&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;ColumnName&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ConvertCarriageReturnForSaves(DataTable dt, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ColumnName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dt.Columns.Contains(ColumnName))&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; dt.Rows.Count; i++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dt.Rows[i][ColumnName] != DBNull.Value)&lt;br /&gt;                    dt.Rows[i][ColumnName] = dt.Rows[i][ColumnName].ToString().Replace(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CRLF, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewLine);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Use the methods like this in your Web Service classes:&lt;/p&gt;&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;[WebService(Namespace = &lt;span style="color: #cc6633"&gt;&amp;quot;http://mycompany.com/&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Customer : BBWebServices&lt;br /&gt;{&lt;br /&gt;    [WebMethod(Description=&lt;span style="color: #cc6633"&gt;&amp;quot;Returns Customer Info for one customer&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetCustomer(&lt;span style="color: #0000ff"&gt;long&lt;/span&gt; CustomerKey)&lt;br /&gt;    {&lt;br /&gt;        CustomerBiz oBiz = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerBiz();&lt;br /&gt;        CustomerDataSet ds = oBiz.GetCustomer(CustomerKey);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConvertCarriageReturnForGets(ds.CustomerNotes, &lt;span style="color: #cc6633"&gt;&amp;quot;notes&amp;quot;&lt;/span&gt;);&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; XML = ds.GetXml();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; XML;&lt;br /&gt;    }&lt;br /&gt;    [WebMethod(Description=&lt;span style="color: #cc6633"&gt;&amp;quot;Saves info for one customer&amp;quot;&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SaveCustomer(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ChangeXML, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DeleteXML)&lt;br /&gt;    {&lt;br /&gt;        CustomerDataSet dsChanged = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerDataSet();&lt;br /&gt;        CustomerDataSet dsDeleted = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerDataSet();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// FillWithXml() is a method I have defined in my DataSet classes&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;// It simply uses the DataSet's ReadXml() method with a string reader&lt;/span&gt;&lt;br /&gt;            dsChanged.FillWithXml(ChangeXML);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (DeleteXML != &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;br /&gt;                dsDeleted.FillWithXml(DeleteXML);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            Message = ex.Message;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        CustomerBiz oBiz = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerBiz();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConvertCarriageReturnForSaves(dsChanged.CustomerNotes, &lt;span style="color: #cc6633"&gt;&amp;quot;notes&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsOK = o.SaveCustomer(dsChanged, dsDeleted);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; IsOK;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-8151957243602165537?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/8151957243602165537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dealing-with-carriage-returns-in-web.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8151957243602165537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/8151957243602165537'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dealing-with-carriage-returns-in-web.html' title='Dealing with Carriage Returns in Web Service Methods'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-1526067906408731741</id><published>2009-10-04T17:46:00.001-07:00</published><updated>2009-10-27T13:12:24.042-07:00</updated><title type='text'>DataAccess – Part II</title><content type='html'>&lt;p&gt;In &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html"&gt;Part I&lt;/a&gt; of this topic, I tried to explain the basic functionality you should strive for in a DataAccess layer in your applications:&lt;/p&gt; &lt;ul&gt;   &lt;li&gt;Keep the DataAccess totally separate from your UI layer. &lt;/li&gt;   &lt;li&gt;Pass data objects between the layers. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In Part II, I will attempt to show you how to abstract your DataAccess layer one more step. The key is to program to the IDb interfaces, as I will show below.&lt;/p&gt; &lt;p&gt;My DataAccess layer has two base classes: BBConnection and BBDataAccess. All the methods are coded to the various DataAccess Interfaces (the IDb interface objects). DataSets are used simply for transporting data back and forth. I know that there are plenty of camps who advocate Biz objects for this, but I'm a believer of Typed DataSets for transporting my data between front-end and back-end. &lt;/p&gt; &lt;p&gt;The BBConnection class basically has a GetConnection() method that finds the Connection String from the app's config info and returns an instantiated Connection. It returns it as an interface, the IDbConnection. &lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// For another type of database, replace the SqlConnection in the constructor&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBConnection&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declaration&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Use a variable to store the connection string, if you try and get it from the SqlConnection object, it strips the password&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ConnectionString = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Methods&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IDbConnection GetConnection()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetConnection(&lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IDbConnection GetConnection(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; tConnectionString)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; cConnection = tConnectionString;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (tConnectionString == &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;br /&gt;            cConnection = ConfigurationSettings.AppSettings[&lt;span style="color: #cc6633"&gt;&amp;quot;ConnectionString&amp;quot;&lt;/span&gt;];&lt;p&gt;&lt;/p&gt;        SqlConnection conn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(cConnection);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConnectionString = cConnection;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; conn;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Probably a slightly better design than what I show below, would be to use a Factory Pattern ... but my code was initially refactored from more tightly-coupled-to-SQL code, and at the time was easier done the way I did it. I'll leave that as an exercise for the reader! ;-) &lt;/p&gt;
&lt;p&gt;The BBDataAccess class, simplified, is something like this:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBDataAccess&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbConnection oConnection;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbCommand oCommand;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDbDataAdapter oAdapter;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDataParameterCollection oParms;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ConnectionString = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ErrorMessage = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Constructor/Destructor&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBDataAccess()&lt;br /&gt;    {&lt;br /&gt;        BBConnection o = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BBConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection = o.GetConnection();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ConnectionString = o.ConnectionString;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbCommand();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oAdapter = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbDataAdapter(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Connection = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandType = CommandType.StoredProcedure;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Get/Use IDb Interface Objects&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbCommand GetIDbCommand()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbDataAdapter GetIDbDataAdapter(IDbCommand command)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter((SqlCommand)command);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; IDbDataParameter GetIDbDataParameter(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlParameter(ParmName, ParmValue);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DeriveParameters(IDbCommand command)&lt;br /&gt;    {&lt;br /&gt;        SqlCommandBuilder.DeriveParameters((SqlCommand)command);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// Then there are the various protected methods for adding and setting Parameters, filling a DataSet, etc.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// It's these various methods that get used in the classes that are sub-classed from this &amp;quot;base&amp;quot; class.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// Here's just a few of them:&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClearParameters()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.Clear();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddParms(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ParmName.StartsWith(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;                ParmName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AtSign + ParmName;&lt;p&gt;&lt;/p&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ParmValue != DBNull.Value)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.Add(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetIDbDataParameter(ParmName, ParmValue));&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage += ex.Message;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddParms(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; ParmValue, ParameterDirection direction)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddParms(ParmName, ParmValue);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetParmDirection(ParmName, direction);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; FillData(DataSet ds, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; StoredProcName)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oCommand.CommandText = StoredProcName;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oAdapter.Fill(ds);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ErrorMessage += ex.Message;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CloseConnection();&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;&lt;/div&gt;
&lt;p&gt;In this way, your DataAccess sub-classes are totally &amp;quot;disassociated&amp;quot; from knowing what your back-end data is (could be SqlServer, as the above class is, but if you also have an Oracle customer, you have another base class exactly the same as the above class, but it uses Oracle-specific stuff instead and you use the appropriate DLL depending on your which database your customer has ... however, you're still programming to the interface (the IDb Interface objects), so your sub-classes, which are in different projects (and thus different DLLs) don't care and don't need to be changed. &lt;/p&gt;
&lt;p&gt;So, an example of a sub-class might be this:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CustomerAccess : BBDataAccess&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Public Get Methods&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DataSet GetCustomerInfo(&lt;span style="color: #0000ff"&gt;long&lt;/span&gt; CustomerKey)&lt;br /&gt;    {&lt;br /&gt;        CustomerDataSet ds = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomerDataSet();&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClearParameters();&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AddParms(&lt;span style="color: #cc6633"&gt;&amp;quot;CustomerKey&amp;quot;&lt;/span&gt;, CustomerKey);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FillData(ds, &lt;span style="color: #cc6633"&gt;&amp;quot;csp_Customer_Get&amp;quot;&lt;/span&gt;);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ds;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;// more methods&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="color: #cc6633"&gt;UPDATE:&lt;/span&gt; Since posting my 2-part DataAccess "article", I've realized that it should have been 3-part. There's another, better methodology for DataAccess that I've used and I'd like to show you all. So, see &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html"&gt;Part III&lt;/a&gt; of my series.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-1526067906408731741?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/1526067906408731741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1526067906408731741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/1526067906408731741'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html' title='DataAccess – Part II'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-4588757395398925385</id><published>2009-09-29T16:55:00.001-07:00</published><updated>2011-10-08T21:59:51.844-07:00</updated><title type='text'>DataAccess – Part I</title><content type='html'>&lt;p&gt;DataAccess in Windows Forms is a much misunderstood concept. I cannot count the number of times I see people dropping DataAdapters and TableAdapters directly on a Form and accessing their database directly from the Form in this manner. This is a major no-no!! &lt;/p&gt;  &lt;p&gt;The DataAccess classes should be totally separated from your User Interface (UI) or, as some people prefer to call it, the Presentation Layer. And forget TableAdapters (see my blog &lt;a href="http://geek-goddess-bonnie.blogspot.com/2009/09/tableadapters-are-crap.html"&gt;post&lt;/a&gt; about them)!&lt;/p&gt;  &lt;p&gt;Interaction between the DataAccess layer and the UI layer can be done with either Business object classes or, as I prefer, with DataSets (preferably, strongly Typed DataSets).&lt;/p&gt;  &lt;h4&gt;Base DataAccess Class&lt;/h4&gt;  &lt;p&gt;First, you need to have a base DataAccess class that all of your other DataAccess classes should inherit from, and get the connection in it's constructor: Let’s start with the simple DataAccess examples and work to the more complex (but more flexible) version in &lt;strong&gt;Part II&lt;/strong&gt; of this blog.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;   &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;     &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;       &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BBDataAccess&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; SqlConnection oConnection;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; BBDataAccess&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Note that I wouldn't actually hard-code the connection string like this. &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// It should be in your config settings. &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Old (1.1), obsolete but still works:&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// string MyConnString = System.Configuration.ConfigurationSettings.AppSettings[&amp;quot;ConnectionString&amp;quot;];&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Current (2.0)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// string MyConnString = System.Configuration.&lt;strong&gt;ConfigurationManager&lt;/strong&gt;.AppSettings[&amp;quot;ConnectionString&amp;quot;];&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;       &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(&lt;span style="color: #cc6633"&gt;&amp;quot;server=(local);database=MyDataBase;uid=sa;pwd=MyPassword&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Depending on how complicated your application is, you may want to have a separate DataAccess class for different functionality, each one sub-classing from the BBDataAccess base class. &lt;/p&gt;

&lt;h4&gt;Getting Data&lt;/h4&gt;

&lt;p&gt;Retrieving the data is easy. Note that this DataAccess method returns a DataSet, as mentioned above:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyDataAccess : BBDataAccess&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DataSet GetMyData()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// Note that a Fill does not require a Connection Open/Close. The Fill leaves&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// the connection in the state it was found (leaves it open if it was open, &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #008000"&gt;// and if it was closed, it opens it, Fills, then closes again).&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;        SqlDataAdapter da = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(&lt;span style="color: #cc6633"&gt;&amp;quot;select * from bob&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection);&lt;br /&gt;        DataSet ds = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataSet();&lt;br /&gt;        da.Fill(ds, &lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;);&lt;br /&gt;    &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ds;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4&gt;Saving Data&lt;/h4&gt;

&lt;p&gt;You have a few more options when updating the database. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;h5&gt;DataAdapter.Update() method, with CommandBuilder&lt;/h5&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, you can use the Update method of the DataAdapter. In order for this to work, the tables in your database must have a PrimaryKey defined. &lt;/p&gt;

&lt;p&gt;You can do it using the CommandBuilder, which will generate update commands for you. (&lt;strong&gt;&lt;u&gt;Note&lt;/u&gt;&lt;/strong&gt;: if you use a Stored Proc, the CommandBuilder only generates the proper insert/update/delete commands for the first table retreived from the Stored Proc.) (&lt;strong&gt;&lt;u&gt;Another Note&lt;/u&gt;&lt;/strong&gt;: using the CommandBuilder entails an extra round-trip to the server.):&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateMyData(DataSet ds)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// The same applies for the Update. It's not necessary to Open/Close the connection.&lt;/span&gt;&lt;br /&gt;    SqlDataAdapter da = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(&lt;span style="color: #cc6633"&gt;&amp;quot;select * from bob&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection);&lt;br /&gt;    SqlCommandBuilder sb = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommandBuilder(da);&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;    da.Update(ds);&lt;br /&gt;}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;h5&gt;Without CommandBuilder&lt;/h5&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or you can create the various update commands yourself instead of using the CommandBuilder:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateMyData(DataSet ds)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    SqlCommand sc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand();&lt;br /&gt;    sc.Connection = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection;&lt;br /&gt;    da = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlDataAdapter(sc);&lt;br /&gt;&lt;br /&gt;    da.InsertCommand = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand(&lt;span style="color: #cc6633"&gt;&amp;quot;Insert into bob (xyz, abc) VALUES ( @xyz, @abc )&amp;quot;&lt;/span&gt;, sc.Connection);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #008000"&gt;// Note that with these parameters, the update will simply insert &amp;quot;xyz&amp;quot; and &amp;quot;abc&amp;quot; &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// into every inserted row. Probably not what you want. &lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// See the Do-It-Yourself option below for a better idea.&lt;/span&gt;&lt;br /&gt;    da.InsertCommand.Parameters.AddWithValue(&lt;span style="color: #cc6633"&gt;&amp;quot;@xyz&amp;quot;&lt;/span&gt;, &lt;span style="color: #cc6633"&gt;&amp;quot;xyz&amp;quot;&lt;/span&gt;);&lt;br /&gt;    da.InsertCommand.Parameters.AddWithValue(&lt;span style="color: #cc6633"&gt;&amp;quot;@abc&amp;quot;&lt;/span&gt;, &lt;span style="color: #cc6633"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;);    &lt;br /&gt; &lt;br /&gt;    &lt;span style="color: #008000"&gt;// do the same for da.DeleteCommand &amp;amp; da.UpdateCommand&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;    da.Update(ds);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;h5&gt;Do-It-Yourself&lt;/h5&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or, you can take total control, not use the da.Update() and do it all yourself (this is basically the same code that gets done behind the scenes by the da.Update() method:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:2dc053a9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateMyData(DataSet ds)&lt;br /&gt;{&lt;br /&gt;    SqlCommand sc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlCommand();&lt;br /&gt;    sc.Connection = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oConnection;&lt;br /&gt;    sc.Connection.Open();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (DataRow Row &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; ds.Tables[0].Rows)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (Row.RowState)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; DataRowState.Added :&lt;br /&gt;                &lt;span style="color: #008000"&gt;// or use a StoredProc, which I prefer&lt;/span&gt;&lt;br /&gt;                sc.CommandText = &lt;span style="color: #cc6633"&gt;&amp;quot;Insert into bob (xyz, abc) VALUES ( @xyz, @abc )&amp;quot;&lt;/span&gt;;&lt;br /&gt;                sc.Parameters.Clear();&lt;br /&gt;                sc.Parameters.Add(&lt;span style="color: #cc6633"&gt;&amp;quot;@xyz&amp;quot;&lt;/span&gt;, Row[&lt;span style="color: #cc6633"&gt;&amp;quot;xyz&amp;quot;&lt;/span&gt;]);&lt;br /&gt;                sc.Parameters.Add(&lt;span style="color: #cc6633"&gt;&amp;quot;@abc&amp;quot;&lt;/span&gt;, Row[&lt;span style="color: #cc6633"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;]);&lt;br /&gt;                sc.ExecuteNonQuery();&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;                &lt;br /&gt;            &lt;span style="color: #008000"&gt;// Do the same for DataRowState Deleted and Modified&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; DataRowState.Deleted :&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; DataRowState.Modified :&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    sc.Connection.Close();&lt;br /&gt;}&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4&gt;Summary&lt;/h4&gt;

&lt;p&gt;So, that’s it for this blog. In Part II, I’ll discuss creating a base DataAccess class by programming to the various IDb interfaces. By doing this, all your DataAccess sub-classes are totally &amp;quot;disassociated&amp;quot; from knowing what your back-end database is. Stay tuned …&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-4588757395398925385?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/4588757395398925385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html#comment-form' title='32 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/4588757395398925385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/4588757395398925385'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html' title='DataAccess – Part I'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>32</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-5060157099077779536</id><published>2009-09-25T08:33:00.001-07:00</published><updated>2009-09-25T08:36:05.382-07:00</updated><title type='text'>Deleting DataRows</title><content type='html'>&lt;p&gt;This will seem, to many, to be a really elementary, very basic, newbie (or, noobie if you prefer) sort of topic. And it is. But, I still see questions about deleting DataRows asked a great many times on the Forums.&lt;/p&gt; &lt;p&gt;Most people are used to looping through rows in a DataView using either for or foreach loops, starting at 0 until the you've finished iterating through all the rows. This works fine &lt;strong&gt;&lt;em&gt;except&lt;/em&gt;&lt;/strong&gt; in the case where you're deleting rows along the way. In this case, you should use a for loop and iterate &lt;strong&gt;&lt;em&gt;backwards&lt;/em&gt;&lt;/strong&gt; through the DataView. This is true whether it's the DefaultView of a DataTable or your own DataView that you’ve created.&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i= MyView.Count-1; i &amp;gt;=0; i--)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (MyView[i][&lt;span style="color: #cc6633"&gt;&amp;quot;MyCriteria&amp;quot;&lt;/span&gt;].ToString() == &lt;span style="color: #cc6633"&gt;&amp;quot;DeleteMe&amp;quot;&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        MyView[i].Delete();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// do some processing here&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;So, why does this cause problems if you don't iterate backwards? Because, once a Row is marked as Deleted, it's gone from the DataView (since, typically, DataViews do not include Deleted rows), and if you were iterating forward through the DataView, you'd end up skipping past the row immediately after the one that was just deleted thereby not processing every row in your view. &lt;/p&gt;&lt;p&gt;Deleting backwards through the DataView gets around this problem. As does deleting from the DataTable (in either direction) instead of a DataView (although this may not always be the best solution, depending your processing needs).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-5060157099077779536?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/5060157099077779536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/deleting-datarows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5060157099077779536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/5060157099077779536'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/deleting-datarows.html' title='Deleting DataRows'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-11771736316257655</id><published>2009-09-22T08:54:00.001-07:00</published><updated>2010-04-18T09:18:49.942-07:00</updated><title type='text'>TableAdapters Are Crap!</title><content type='html'>&lt;p&gt;I haven't played around that much with TableAdapters, mainly because what I *have* seen, I didn't like. The TableAdapter Wizard puts crap into my .xsd that certainly doesn't belong there, such as connection strings. My DataSet .xsd's should be DataSet schema and that is all! The wizard *totally* messed with my existing .xsd and I just don't like all the extra stuff it put in there. &lt;/p&gt;  &lt;p&gt;I have heard people say that the TableAdapter stuff can be decoupled from the generated DataSet (which it should be, IMHO ... DataAccess stuff has no business being in a DataSet), but I didn't see any automated way to do it ... just cut/paste elsewhere manually and then of course you'd need to do that each time you made changes (I may have missed something though). &lt;/p&gt;  &lt;p&gt;Another thing, it seems to generate code only for one DataTable ... even though my StoredProc returns many tables and my .xsd contains many tables. I may have missed something, but this is what it looks like to me. If this is the case, this is totally useless to me. &lt;/p&gt;  &lt;p&gt;One of the problems that I see with the TableAdapter is the inflexibility. The generated class tightly-couples the DataSet to the database, and I don't believe that DataSets should be used that way. I use DataSets simply as a data transport mechanism. My DataSets know nothing about where their data comes from, nor should they. &lt;/p&gt;  &lt;p&gt;OK, technically speaking, the DataSet class doesn't know about where its data comes from, just because I'm using a TableAdapter. But the fact the TableAdapter gets generated inside the DataSet.designer.cs means that the DataSet DLL is no longer database agnostic, and that's a very bad thing for correct client-server / SOA architecture. There is no more separation of layers when done this way. The DataAccess classes should be a totally separate layer with their own DLLs, just as the DataSet should live in their own DLLs. &lt;/p&gt;  &lt;p&gt;My advice is to skip the TableAdapter Wizard ... it generates a lot of bloated and useless code and you could code it up yourself just as easily and more efficiently. Some of it may be useful to initially see how things work maybe, but then you should just use the DataAdapters yourself instead of using a TableAdapter which basically “wraps” the DataAdapter.&amp;#160; This is just my opinion, so take it for what it's worth. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;UPDATE 4/18/2010:&lt;/font&gt; &lt;/strong&gt;I have another related post that may be useful to readers of this post. Please check out my post: &lt;a href="http://geek-goddess-bonnie.blogspot.com/2010/04/create-xsd.html" target="_blank"&gt;Create An Xsd&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-11771736316257655?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/11771736316257655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/tableadapters-are-crap.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/11771736316257655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/11771736316257655'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/tableadapters-are-crap.html' title='TableAdapters Are Crap!'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-2162934823332334039</id><published>2009-09-21T17:59:00.001-07:00</published><updated>2009-09-21T17:59:42.049-07:00</updated><title type='text'>Fun With DataSets</title><content type='html'>&lt;p&gt;Data in a DataRow has several different versions. First, there's the original version. Then, when it's being edited (either in a UI control, like a TextBox or programmatically), it has a Proposed version and once it's done being edited, that becomes the Current version. Sometimes when entering data in a UI control, the row is left in the Proposed state and the Edit needs to be ended programmatically. This doesn't always happen and I'm not entirely sure why it's seemingly random (maybe it's an ADO.NET bug). &lt;/p&gt; &lt;p&gt;Say, for example, that you have made only one change in your entire DataSet and, for that unexplained reason, the DataRow is still in its Proposed version. If you check the DataSet.HasChanges() method, it will return a false. If you do a DataSet.GetChanges() you will not get anything returned. That's not a good thing. &lt;/p&gt; &lt;p&gt;But there's a solution to this little gotcha: here's a method I *always* call before I attempt to check for .HasChanges() or do a .GetChanges() before saving data:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CommitProposedChanges(DataSet ds)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ds == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; nTable = 0; nTable &amp;lt; ds.Tables.Count; nTable++)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; nRow = 0; nRow &amp;lt; ds.Tables[nTable].Rows.Count; nRow++)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ds.Tables[nTable].Rows[nRow].HasVersion(DataRowVersion.Proposed))&lt;br /&gt;            {&lt;br /&gt;                ds.Tables[nTable].Rows[nRow].EndEdit();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-2162934823332334039?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/2162934823332334039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/fun-with-datasets.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2162934823332334039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/2162934823332334039'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/fun-with-datasets.html' title='Fun With DataSets'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-3694910905092164344</id><published>2009-09-18T17:20:00.001-07:00</published><updated>2009-10-18T09:43:52.334-07:00</updated><title type='text'>Keeping DataGrids And Other UI Controls In Sync</title><content type='html'>&lt;p&gt;Have you ever noticed that sometimes your databound WinForm controls don't seem to want to stay in sync? Most likely you have a problem with the way you're databinding the controls. This is pretty elementary and basic stuff, but you may be surprised at how often I see questions about this very thing.&lt;/p&gt; &lt;p&gt;There are two ways (two different syntaxes) to specify databinding for any control and this results in two distinct binding objects. The problem is that you can't mix and match ... you have to stay consistent throughout the form.&lt;/p&gt; &lt;p&gt;Here are examples of the two different syntaxes:&lt;/p&gt; &lt;div&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;// If you bound your DataGrid with:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oGrid.DataSource = MyDataSet;&lt;br&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oGrid.DataMember = &lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #008000"&gt;// Then you have to use the following syntax with TextBoxes:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtLastName.DataBindings.Add(&lt;span style="color: #cc6633"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, MyDataSet, &lt;span style="color: #cc6633"&gt;&amp;quot;MyTable.LastName&amp;quot;&lt;/span&gt;);&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;p&gt;&lt;span style="color: #008000"&gt;//But if you bound your grid with:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.oGrid.DataSource = MyDataSet.Tables[&lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;];&lt;br /&gt; &lt;br /&gt;&lt;span style="color: #008000"&gt;//Then you use this syntax for TextBoxes:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.txtLastName.DataBindings.Add(&lt;span style="color: #cc6633"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, MyDataSet.Tables[&lt;span style="color: #cc6633"&gt;&amp;quot;MyTable&amp;quot;&lt;/span&gt;], &lt;span style="color: #cc6633"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;);&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Personally, I prefer the second syntax and use it religiously.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-3694910905092164344?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/3694910905092164344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/keeping-datagrids-and-other-ui-controls.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3694910905092164344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/3694910905092164344'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/keeping-datagrids-and-other-ui-controls.html' title='Keeping DataGrids And Other UI Controls In Sync'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-826630980469074203</id><published>2009-09-17T15:15:00.000-07:00</published><updated>2009-11-20T21:43:06.945-08:00</updated><title type='text'>Reflection in .NET</title><content type='html'>&lt;p&gt;&lt;span style="font-family: arial"&gt;&lt;font color="#ff0000" size="3"&gt;UPDATE (11/20/09):&lt;/font&gt; There was a bug of sorts in the MyReflectionClass posted below. It was in the LoadAssembly() method and it’s been corrected, because we really &lt;strong&gt;do&lt;/strong&gt; have to take into account a path to the Assembly.&amp;#160; Sorry for any confusion or pulling of hair that this has caused. =0(&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family: arial"&gt;This is probably one of the most asked questions I see: How can I dynamically instantiate a class from a string containing the name of the class? And here is what I always reply to that question:      &lt;br /&gt;     &lt;br /&gt;Reflection is a handy way to not only dynamically load controls, but also to dynamically download server-side components automatically.      &lt;br /&gt;     &lt;br /&gt;Below is a simplified version of a Reflection class (other things could be added to it, for example allowing parameters to be passed).      &lt;br /&gt;     &lt;br /&gt;It's easy to use too. Here's one way to use it:&lt;/span&gt;&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;MyReflectionClass oReflection = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyReflectionClass(assembly, classname);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; message = &lt;span style="color: #cc6633"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; o = oReflection.InstantiateClass(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; message);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (o == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;    MessageBox.Show(message);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// go on with your processing&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style="font-family: arial"&gt;And here's the simplified class: &lt;/span&gt;&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 10pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; direction: ltr; border-top-style: none; line-height: 10pt; padding-top: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #e8d8b7; text-align: left; border-bottom-style: none"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyReflectionClass&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Declarations&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_AssemblyName;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_ClassName;&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Constructors&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyReflectionClass()&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// If your Assemblies live in places other than the same path as your app,&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// you’ll need to modify this class to include code for obtaining the full path.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;/// This full-path could be a local path, or a server URL path.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyReflectionClass(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; assemblyName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; className)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.AssemblyName = assemblyName;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClassName = className;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Methods&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Assembly LoadAssembly(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Message)&lt;br /&gt;    {&lt;br /&gt;        Assembly oAssembly = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;&lt;span style="color: #008000"&gt;            // In my real class, I have configuration classes that handles this&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PathOrURL = MethodToObtainPathOrURL(); &lt;br /&gt;            oAssembly = Assembly.LoadFrom(PathOrURL + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName + &lt;span style="color: #cc6633"&gt;&amp;quot;.DLL&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (System.IO.FileNotFoundException)&lt;br /&gt;        {&lt;br /&gt;            Message = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName + &lt;span style="color: #cc6633"&gt;&amp;quot; could not be found at the specified URL!&amp;quot;&lt;/span&gt; + (&lt;span style="color: #0000ff"&gt;char&lt;/span&gt;)13 + (&lt;span style="color: #0000ff"&gt;char&lt;/span&gt;)13 +&lt;br /&gt;                &lt;span style="color: #cc6633"&gt;&amp;quot;Check that you have correctly entered the component URL and that your network or Internet &amp;quot;&lt;/span&gt; +&lt;br /&gt;                &lt;span style="color: #cc6633"&gt;&amp;quot;connection is functioning correctly.&amp;quot;&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oAssembly;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (System.BadImageFormatException)&lt;br /&gt;        {&lt;br /&gt;            Message = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName + &lt;span style="color: #cc6633"&gt;&amp;quot; is invalid or damaged!&amp;quot;&lt;/span&gt; + (&lt;span style="color: #0000ff"&gt;char&lt;/span&gt;)13 + (&lt;span style="color: #0000ff"&gt;char&lt;/span&gt;)13 +&lt;br /&gt;                &lt;span style="color: #cc6633"&gt;&amp;quot;Contact your system administrator.&amp;quot;&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oAssembly;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (System.Exception ex)&lt;br /&gt;        {&lt;br /&gt;            Message = ex.Message;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oAssembly;&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oAssembly;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; InstantiateClass(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Message)&lt;br /&gt;    {&lt;br /&gt;        Assembly oAssembly = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.InstantiateClass(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; oAssembly, &lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; Message);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; InstantiateClass(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; Assembly oAssembly, &lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Message)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; oClass = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (oAssembly == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; || oAssembly.FullName.Contains(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;            oAssembly = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LoadAssembly(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; Message);&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// Create an instance of the desired type from the assembly&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (oAssembly != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                oClass = oAssembly.CreateInstance(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            Message = ex.Message;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oClass;&lt;br /&gt;        }&lt;p&gt;&lt;/p&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; oClass;&lt;br /&gt;    }&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;p&gt;&lt;/p&gt;    &lt;span style="color: #008000"&gt;#region&lt;/span&gt; Properties&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; AssemblyName&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName; }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;.Trim();&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName.ToUpper().EndsWith(&lt;span style="color: #cc6633"&gt;&amp;quot;.DLL&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;))&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName.Remove(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName.Length - 4);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ClassName&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName; }&lt;br /&gt;        set &lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;.Trim(); &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName.Contains(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_AssemblyName + &lt;span style="color: #cc6633"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; + &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ClassName;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #008000"&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-826630980469074203?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/826630980469074203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/reflection-in-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/826630980469074203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/826630980469074203'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/reflection-in-net.html' title='Reflection in .NET'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-7403063406023937759</id><published>2009-09-14T14:13:00.000-07:00</published><updated>2009-09-14T14:23:24.471-07:00</updated><title type='text'>3 Years Later</title><content type='html'>Wow, how time flies! Three years ago, I thought I'd try my hand at blogging. Guess what ... didn't do a thing! But I have a great excuse ... that was just about the time that things started getting crazy at work. 

Well, I don't have to worry about that any more. I have joined the ranks of the unemployed ... unfortunately ... and through no fault of my own, I might add.

So, now is a good time to start putting more of an effort into this blogging thing I think. For my blog posts here, I intend to utilize the questions (and my answers) to the thousands of forum threads I've participated in over the last 7 years (I'm just guessing ... I didn't actually count them to see if there are thousands ... seems like it though).

Might be interesting. Might be informative. Might also be boring, but we'll see. ;0)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-7403063406023937759?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/7403063406023937759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/3-years-later.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7403063406023937759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/7403063406023937759'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2009/09/3-years-later.html' title='3 Years Later'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33753991.post-115720868396839124</id><published>2006-09-02T07:49:00.000-07:00</published><updated>2011-09-29T08:26:22.260-07:00</updated><title type='text'>My First Blog</title><content type='html'>&lt;p&gt;Can you believe it? I am &lt;strong&gt;such&lt;/strong&gt; a geek and yet, until now, had not fallen for the blog craze. I created this one on a whim this morning. We'll see how well I keep it up.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/font&gt;: This was added long after (several years!!): I’m using this post to test some code snippet plug-ins. This post can certainly be ignored!&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:36efab4a-1db0-4a8e-8e17-48bc23c8a0d2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #e8d8b7; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; SetParmDirection(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; ParmName, &lt;span style="color:#2b91af"&gt;ParameterDirection&lt;/span&gt; direction)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (ParmName.StartsWith(&lt;span style="color:#a31515"&gt;&amp;quot;@&amp;quot;&lt;/span&gt;) == &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;)&lt;br&gt;         ParmName = &lt;span style="color:#a31515"&gt;&amp;quot;@&amp;quot;&lt;/span&gt; + ParmName;&lt;br&gt; &lt;br&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters.IndexOf(ParmName) &amp;gt; -1)&lt;br&gt;         &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.oCommand.Parameters[ParmName].Direction = direction;&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; Another plug-in:   &lt;p&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;SetParmDirection(&lt;span style="color: blue"&gt;string &lt;/span&gt;ParmName, &lt;span style="color: #2b91af"&gt;ParameterDirection &lt;/span&gt;direction)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(ParmName.StartsWith(&lt;span style="color: #a31515"&gt;&amp;quot;@&amp;quot;&lt;/span&gt;) == &lt;span style="color: blue"&gt;false&lt;/span&gt;)
        ParmName = &lt;span style="color: #a31515"&gt;&amp;quot;@&amp;quot; &lt;/span&gt;+ ParmName;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.oCommand.Parameters.IndexOf(ParmName) &amp;gt; -1)
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.oCommand.Parameters[ParmName].Direction = direction;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And now I’m going to test a combination of the two. This is tricky in that I have to steal the div tags from the first plug-in and wrap them around the html from the second plug-in … making sure to change the ids as well. Let’s see if this works well or not:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:36efab4a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// ds20 is a 2.0 Typed DataSet, which uses plain a plain old DataTable

&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt20 = ds20.Personnel.DefaultView.ToTable(&lt;span style="color: blue"&gt;true&lt;/span&gt;);

&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dtLinq = ds20.Personnel.AsEnumerable()
    .Select(row =&amp;gt; row).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default)
    .CopyToDataTable();
&lt;span style="color: green"&gt;// Note that if you MUST use the DataRowComparer.
// If you don't you get all rows returned ... it won't find the duplicates.
&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And another:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:9ce6104fc:36efab4a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div style="border-right: #000080 1px solid; border-top: #000080 1px solid; font-size: 10pt; border-left: #000080 1px solid; color: #000; border-bottom: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace"&gt;
    &lt;div style="padding-right: 5px; padding-left: 5px; padding-bottom: 2px; overflow: auto; padding-top: 2px; background-color: #e8d8b7"&gt;
      &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// ds35 is the 3.5 Typed DataSet
// note that the only difference in syntax is that you don't need .AsEnumerable()
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable &lt;/span&gt;dt35 = ds35.Personnel.Select(row =&amp;gt; row).Distinct(&lt;span style="color: #2b91af"&gt;DataRowComparer&lt;/span&gt;.Default).CopyToDataTable();&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;OK … so it displays fine in my editor. Let’s publish it now to the blog and make sure it’s still OK.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33753991-115720868396839124?l=geek-goddess-bonnie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geek-goddess-bonnie.blogspot.com/feeds/115720868396839124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2006/09/my-first-blog.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/115720868396839124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33753991/posts/default/115720868396839124'/><link rel='alternate' type='text/html' href='http://geek-goddess-bonnie.blogspot.com/2006/09/my-first-blog.html' title='My First Blog'/><author><name>Bonnie</name><uri>http://www.blogger.com/profile/11241425687786973525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://photos1.blogger.com/blogger/2841/3710/1600/Bonnie.jpg'/></author><thr:total>3</thr:total></entry></feed>
