<?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'><id>tag:blogger.com,1999:blog-3887765047062401926</id><updated>2009-11-22T20:00:35.265-05:00</updated><title type='text'>Tom Becker</title><subtitle type='html'>.Net, SQL and softball. Musings of a software developer with a softball problem</subtitle><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/default.htm'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default?start-index=26&amp;max-results=25'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.tombecker.net/atom.xml'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>82</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-1260504491168199257</id><published>2009-11-22T19:43:00.003-05:00</published><updated>2009-11-22T20:00:35.277-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Back to Basics'/><title type='text'>Back to Basics:  Looping</title><content type='html'>Pretty soon after learning conditional statements comes looping.  Looping can be used to scan through a recordset, or to add items to a drop down or any number of things really.  Looping is vital to almost any program.  Today we will learn how to use for loops and while loops in both C# and VB.&lt;br /&gt;&lt;h3&gt;For-Loop&lt;/h3&gt;In both C# and VB the for loop can come in two flavors.  The more traditional what I will call the counting for loop, and a for each loop which will allow you to loop through a collection or enumeration of things. &lt;br /&gt;&lt;br /&gt;First we will start off with the counting for loop.  There are three main parts to this for loop. First is the counter and it's initialization.  You can either define this outside of the loop and just reference it in the loop, or you can define it inline with the loop.  This is the the method I prefer since the scope of the variable is localized to the for loop. Traditionally the counter variables are 'i', 'j', or 'k'. There is nothing wrong with using other variable names, but you will see these 3 used all the time.  More often than not you will see 'i' being the most prevalent.&lt;br /&gt;&lt;br /&gt;The second part is the ending criteria such as an upper or lower bound, it is essentially how many times the loop will execute.  This is a very important piece because if you don't have it then you will enter into an infinite loop in which there is no way your program will exit until you run out of memory or hit the upper bound of the data type you are using (both are bad things).    Since this is tested at the beginning of each iteration this is called a pre-test loop.&lt;br /&gt;&lt;br /&gt;Lastly we define how are are going to increment our counter.  Many times this is just up by one each time or down by one.  But you can use any increment you wish.  The increment happens after the end of the loop.followed by the check of the counter.  If the ending criteria is not met the loop will execute again.&lt;br /&gt;&lt;br /&gt;In this example we are just going to loop 10 times writing out to the screen the value of i each time&lt;br /&gt;&lt;br /&gt;C#&lt;br /&gt;&lt;pre&gt;//Example 1&lt;br /&gt;for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;    Response.Write("i=" + i.ToString() + "&amp;lt;br/&amp;gt;");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Example 2&lt;br /&gt;int i;&lt;br /&gt;for (i = 0; i &amp;lt; 10; i+=2) {&lt;br /&gt;    Response.Write("i=" + i.ToString() + "&amp;lt;br/&amp;gt;");&lt;br /&gt;}&lt;/pre&gt;You can see how I defined the variable 'i' inside the for loop in the first example. In the second I declared the variable outside of the loop.  Both are valid, and it is just personal preference. Just remember that the scope on each variable is different. &lt;br /&gt;&lt;br /&gt;In the second example above we are incrementing by 2 each time through the loop.  The += notation is the same thing as writing out the full expressoin i = i+2.  It just makes the whole thing easier to read. &lt;br /&gt;&lt;br /&gt;In VB.Net if you are going to increment by 1 each time around you do not need to define the last piece of the loop, it is built in.  So in example 1 below we are just going to count up by one.  In example 2 we will increment by 2 as before.&lt;br /&gt;&lt;br /&gt;VB&lt;pre&gt;//Example&lt;br /&gt;For i As Integer = 0 To 10&lt;br /&gt;    Response.Write("i=" &amp; i &amp; "&amp;lt;br/&amp;gt;")&lt;br /&gt;Next&lt;br /&gt;&lt;br /&gt;//Example 2&lt;br /&gt;For i As Integer = 0 To 10 Step 2&lt;br /&gt;    Response.Write("i=" &amp; i &amp; "&amp;lt;br/&amp;gt;")&lt;br /&gt;Next&lt;/pre&gt;So as you can see in Example 2 using the step clause in VB will allow you to change what you increment (or step) by.&lt;br /&gt;&lt;br /&gt;The next type of For loop is the for each, which is very useful in stepping though a collection of objects.  For example, lets assume we have a collection, addressBook, of people using the class (person) we have been using in the past 2 posts.  The examples are just going to loop through all of the items in the collection.  Note how we do not have to declare a counter.  .Net will handle fetching each item and knowing when to stop.  This loop can be re-written into a counting for loop very easily.  I would be willing to say that each foreach loop could be re-written as a counting for loop, but the reverse isn't true.  I'm not positive on that, but I can't think of any examples to prove me wrong, if you can think of one put it in the comments below.&lt;br /&gt;&lt;br /&gt;C#&lt;pre&gt;foreach (person peep in addressBook) {&lt;br /&gt;    Response.Write(peep.LastName);&lt;br /&gt;}&lt;/pre&gt;VB&lt;pre&gt;For Each peep As person In addressBook&lt;br /&gt;    Response.Write(peep.LastName)&lt;br /&gt;Next&lt;/pre&gt;As you can see the syntax is almost identical between the two languages.&lt;br /&gt;&lt;h3&gt;While Loops&lt;/h3&gt;While have the same purpose as a for loop, and they can be swapped in almost any case, but sometimes it just makes more sense to use a while loop instead of a for loop. &lt;br /&gt;&lt;br /&gt;For example, lets say we have a loop that we really have no way of knowing how many times the loop would need to run.  A great example of this is while reading a file from disk. We want to keep looping until we hit the end of file (EOF) character.  I am sure you could probably find out the length of the file, divide the bytes and use a for loop, but it just feels better to use a while loop.  After programming for a while you will get a good feel of when to use a while loop and when to use a for.&lt;br /&gt;&lt;br /&gt;The first example, is just re-writing the counting loop from above just to show you how it is done. The second example is reading from an OracleDataReader.  I am not going to show the opening of the data reader and all that, but I am just going to loop through it for you and am going to fill our addressBook from before. I am going to use some newer notation (.Net 3.5) to make the code a bit shorter for the initialization of the person object.&lt;br /&gt;&lt;br /&gt;C#&lt;pre&gt;//Example 1&lt;br /&gt;int i;&lt;br /&gt;while (i &amp;lt; 10) {&lt;br /&gt;    Response.Write("i=" + i.ToString());&lt;br /&gt;    i++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Example 2&lt;br /&gt;while (reader.HasRows) {&lt;br /&gt;    person peep = new person { FirstName = reader["FirstName"], LastName = reader["LastName"], Age = reader["Age"] };&lt;br /&gt;    addressBook.Add(peep);&lt;br /&gt;}&lt;/pre&gt;So those are your basic loops.  There is one more type of loop that can be used the do-while. But haven't used that in many years and is only used in a few cases.  The difference being the compiler will check the condition at the end of the loop instead of at the beginning, so your loop will always execute at least once, this is called a post test loop.&lt;br /&gt;&lt;br /&gt;And a special thanks to &lt;a href="http://brenthoard.com/" target="_blank"&gt;Brent&lt;/a&gt; for guest editing this post&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-1260504491168199257?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/1260504491168199257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-looping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1260504491168199257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1260504491168199257'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-looping.html' title='Back to Basics:  Looping'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-8417261285330704667</id><published>2009-11-09T19:00:00.004-05:00</published><updated>2009-11-09T19:09:57.684-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Back to Basics'/><title type='text'>Back to Basics: Conditional Statements</title><content type='html'>This is the second in my Back to Basics series, and this time we are going way back.  Conditional statements are some of the very first things you learn in any introductory programing class.  In this post I will show you the C# and VB syntax for if, if/else, and switch statements.&lt;br /&gt;&lt;h3&gt;If-statement&lt;/h3&gt;We will start off with the simplest of conditional statements, the if-statement.  This is just simple boolean logic that will evaluate true or false.  If the result is true, it will execute the block, if false it will skip it.  In this example we will check to see if a person is over the age of 21.  We will be using the same person class as in my last &lt;a href="http://www.tombecker.net/2009/11/back-to-basics-parameterizing-inline.html"&gt;post&lt;/a&gt;&lt;br /&gt;&lt;br/&gt;C#&lt;pre&gt;if (myPerson.Age &amp;gt;= 21) &lt;br /&gt;     canDrink = true; //Whatever logic you want&lt;br /&gt;&lt;/pre&gt;Notice that in C# you can omit the curly braces ({}) if the logic under the if statement is one line long.  If it is longer than one line you must use the braces.  If you omit those, then the line directly beneath the if statement will be the only one evaluated on a conditional basis the rest of the statements will always be executed. &lt;br /&gt;&lt;br /&gt;However in the VB.Net syntax you must have a closing End If, even if the statement is a single line.&lt;br/&gt;&lt;br /&gt;VB&lt;pre&gt;If myPerson.Age &amp;gt;= 21 Then&lt;br /&gt;    canDrink = true&lt;br /&gt;End If&lt;/pre&gt;&lt;h3&gt;If/Else&lt;/h3&gt;The next example is of an if/else statement.  The same rules apply as before, we are just extending it a bit.  You can chain together as many if/else statements as you wish, just by adding more conditions.  However all of the conditions must before the else, with the else being the final statement (if needed, don't have to have an else).  &lt;br /&gt;&lt;br /&gt;Once the compiler finds a match for your statement it will not execute any more of the statements in your if/else block.  This lets the compiler be more efficient.  &lt;br /&gt;&lt;br/&gt;C#&lt;pre&gt;if (myPerson.Age &amp;lt; 18)&lt;br /&gt;    canDrink = canVote = false;&lt;br /&gt;else if (18 &amp;lt;= myPerson.Age &amp;lt; 21) {&lt;br /&gt;    canVote = true;&lt;br /&gt;    canDrink = false;&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;    canDrink = canVote = true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Note in this example that I mixed my curly braces.  First condition I didn't need them since I had one line.  Second one I did since I have more than one line. And the third I didn't need them but put them anyway. &lt;br /&gt;&lt;br/&gt;VB&lt;pre&gt;If myPerson.Age &amp;lt; 18 Then&lt;br /&gt;    canVote = canDrink = False&lt;br /&gt;ElseIf 18 &amp;lt;= myPerson.Age &amp;lt; 21 Then&lt;br /&gt;    canVote = True&lt;br /&gt;    canDrink = False&lt;br /&gt;Else&lt;br /&gt;    canVote = canDrink = True&lt;br /&gt;End If&lt;/pre&gt;&lt;h3&gt;Switch Statement&lt;/h3&gt;&lt;br /&gt;The switch statement is a little more complicated than the if and if/else statements but it can be very useful and make your code look cleaner in a lot of places.  They can be very useful when evaluating enumerations.  In the example below lets assume that our person class has an enumeration of hair colors called (strangely) HairColors.  So lets use an switch statement to evaluate our public property hair, and do some logic based on hair color.  If the hair color is not in our list the default case will be evaluated.  I realize that since we are using an enum we would never evaluate the default case, but just bear with me.&lt;br /&gt;&lt;br/&gt;C#&lt;pre&gt;switch (myPerson.hair) { &lt;br /&gt;    case HairColors.brown:&lt;br /&gt;       //You are a brunette&lt;br /&gt;       break;&lt;br /&gt;    case HairColors.blonde:&lt;br /&gt;       // you are blonde, duh&lt;br /&gt;       break;&lt;br /&gt;    case HairColors.red:&lt;br /&gt;       //You are a redhead&lt;br /&gt;       break;&lt;br /&gt;    case HairColors.black:&lt;br /&gt;       //You have black hair&lt;br /&gt;       break;&lt;br /&gt;    default: &lt;br /&gt;       //You have colorful hair&lt;br /&gt;       break;&lt;br /&gt;}&lt;/pre&gt;You must use the break statement to end each specific case.  This will exit you out of the enclosing block, in this case the switch.  The break statement can be used in any control flow statement, and it will have the same effect.  In the switch statement though it is required, and the compiler will throw an error if you omit this step.&lt;br /&gt;&lt;br/&gt;VB&lt;pre&gt;Select Case myPerson.hair&lt;br /&gt;    Case HairColors.brown&lt;br /&gt; 'You are a brunette&lt;br /&gt;    Case HairColors.blonde&lt;br /&gt; ' you are blonde, duh&lt;br /&gt;    Case HairColors.red&lt;br /&gt; 'You are a redhead&lt;br /&gt;    Case HairColors.black&lt;br /&gt; 'You have black hair&lt;br /&gt;    Case Else&lt;br /&gt; 'You have colorful hair&lt;br /&gt;End Select&lt;br /&gt;&lt;/pre&gt;In VB, the switch statement is known as a Select Case, and as you can see by the syntax it is very similar to C# other than the naming.  In this case however, you do not need to include the break statement, the flow will stop when it hits the next case keyword.&lt;br /&gt;&lt;br /&gt;As a bonus I will give you one more statement called the ternary operator.  This works very well in C# because of &lt;a href="http://en.wikipedia.org/wiki/Short_circuit_%28programming%29" target="_blank"&gt;short-circuiting&lt;/a&gt;, but in VB you have to be careful because VB won't short circuit.&lt;br /&gt;&lt;br /&gt;You can use the ternary operator to evaluate something and assign a value on one line.  You can easily re-write it to be an if/else statement.  Lets re-write our first statement using a ternary operator.  The first part is your condition. So in this case we are checking to make sure person is over 21.  After the question mark is the true part of the statement and the last is the false.&lt;br /&gt;&lt;br/&gt;C#&lt;pre&gt;canDrink = myPerson.Age &gt;= 21 ? true : false;&lt;/pre&gt;&lt;br /&gt;&lt;br/&gt;VB&lt;pre&gt;canDrink = IIf(myPerson.Age &gt;= 21, True, False)&lt;/pre&gt;&lt;br /&gt;The syntax is very similar, however this isn't a true ternary operator since we are calling a function (iif), but it functions almost exactly the same. The difference being that in VB the second part of the statement (the false section) will still be evaluated.  In this case it wouldn't matter if it is evaluated since nothing can go wrong.  &lt;a href="http://edgewaters.blogspot.com/2008/09/newsflash-iif-is-not-ternary-operator.html" target="_blank"&gt;Check here&lt;/a&gt; for some other reading on the subject of VB and iif.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;So there are your basic control flow and conditional statements.  I hope this was useful, and good luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-8417261285330704667?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/8417261285330704667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-conditional-statements.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8417261285330704667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8417261285330704667'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-conditional-statements.html' title='Back to Basics: Conditional Statements'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2520832273333667460</id><published>2009-11-05T21:20:00.002-05:00</published><updated>2009-11-05T21:23:47.567-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Back to Basics'/><title type='text'>Back to Basics: Parameterizing Inline SQL</title><content type='html'>Things have been a bit slow with any interesting project work and I don't want this blog to fall &lt;span style="text-decoration: line-through;"&gt;even more&lt;/span&gt; stagnant .  So I am going to be writing a new series called "Back to Basics" containing best practices and some basic code references aimed at newer coders.&lt;br /&gt;&lt;br /&gt;There are some situations in which you cannot use stored procedures in order to handle all of your data access.  Some cases it is just because of the architecture where you are at, other times it is because you are building the SQL at run time (this still can be done in both P/L or T-SQL but in this case we are going to write it inline).&lt;br /&gt;&lt;br /&gt;But no matter what the circumstance, it is still good practice to parameterize your statements.  This can help with style as well as helping to protect against &lt;a href="http://en.wikipedia.org/wiki/SQL_injection" target="_blank"&gt;SQL Injection&lt;/a&gt; (Wikipedia).&lt;br /&gt;&lt;br /&gt;We will take a normal inline SQL statement and convert it to a parameterized statement.  We will start with this.&lt;br /&gt;&lt;pre&gt;public void Save() {&lt;br /&gt;&lt;br /&gt;  string sql = "INSERT INTO People (First_Name, Last_Name, Age) VALUES (\"" + this.FirstName + "\", \"" + this.LastName +&lt;br /&gt;   "\", \"" + this.Age + "\");";&lt;br /&gt;&lt;br /&gt;  using (OracleConnection conn = new OracleConnection("connstring"))&lt;br /&gt;   using (OracleCommand comm = new OracleCommand(conn, sql)) {&lt;br /&gt;  comm.CommandType = CommandType.Text;&lt;br /&gt;&lt;br /&gt;  comm.ExecuteNonQuery();&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;This will work as is, and technically is correct.  However, the readability goes out the window.  With all the escape characters and everything in that statement it becomes hard to read very quickly. This is also a very small insert statement.  Imagine a larger table with 15-20 rows.  The statment would become huge and debugging would become hard if you mistyped something, so along with the readability, scaleability is bad as well.&lt;br /&gt;&lt;br /&gt;So lets take that statement and parameterize it.  This adds to the number of lines of code, but in this case it is well worth it.  We take out all of the items in the VALUES clause and replace them with identifiers, much like you would if you were writing a full stored procedure.  Then you can add the parameters to the command object.  With this you can specify data types and sizes to even further restrict the data entered to help make sure no bad data gets through.  This also allows you to significantly shorten your SQL statement, and allows you to add another value much easier than in the previous example.&lt;pre&gt;public void Save() {&lt;br /&gt;&lt;br /&gt;  string sql = "INSERT INTO People (First_Name, Last_Name, Age) VALUES (:FirstName, :LastName, :Age);";&lt;br /&gt;&lt;br /&gt;  using (OracleConnection conn = new OracleConnection("connstring"))&lt;br /&gt;   using (OracleCommand comm = new OracleCommand(conn, sql)) {&lt;br /&gt;  comm.CommandType = CommandType.Text;&lt;br /&gt;&lt;br /&gt;  comm.Parameters.Add(":FirstName", OracleType.VarChar, 50).Value = this.FirstName;&lt;br /&gt;  comm.Parameters.Add(":LastName", OracleType.VarChar, 50).Value = this.LastName;&lt;br /&gt;  comm.Parameters.Add(":Age", OracleType.Int32).Value = this.Age;&lt;br /&gt;&lt;br /&gt;  comm.ExecuteNonQuery();&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This will work for both Oracle and MS SQL, you would just have to change from and Oracle connection and command to a SQL one.  Also I think the preferred syntax when using MS SQL would be to use the @ symbol rather than the colon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2520832273333667460?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2520832273333667460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-parameterizing-inline.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2520832273333667460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2520832273333667460'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/11/back-to-basics-parameterizing-inline.html' title='Back to Basics: Parameterizing Inline SQL'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2001596959660547368</id><published>2009-09-21T11:59:00.004-04:00</published><updated>2009-09-21T13:09:41.870-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Custom Attributes in C#</title><content type='html'>An attribute in C# is a way for you to add meta-data around an element in your code.  You can attach an attribute to many different targets, see &lt;a href="http://oreilly.com/catalog/progcsharp/chapter/ch18.html#14588" target="_blank"&gt;here&lt;/a&gt; for full list.&lt;br /&gt;&lt;br /&gt;Attributes are useful in supplying extra information about the target at all stages of developement, from design to run time.  They help you specify specific information about the target, such as the method type, such as designating a &lt;a href="http://msdn.microsoft.com/en-us/library/byxd99hx%28VS.71%29.aspx" target="_blank"&gt;WebMethod&lt;/a&gt;.  Or to inform the compiler that a method is now obsolete, so that the compiler can warn you that you are using an outdated method.  I think the most recognizable one that I think most people would have used an not even thought about it as an attribute is the &lt;a href="http://blog.kowalczyk.info/article/Serialization-in-C.html" target="_blank"&gt;Serializable.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also create your own custom attributes in C#, and basically all it takes is a small lightweight class that inherits from System.Attribute and has a constructor and some public properties.  These properties can be then read at runtime through reflection.&lt;br /&gt;&lt;br /&gt;In this example, we are going to create an attribute to denote a field that we can expect in an import from a user.  So first we create the attribute.  We are going to require that we have 3 pieces of meta-data in our attribute, a display name, whether or not the field is required in the upload, and a description of the field (used for display purposes).  So let's create the class&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;[System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)]&lt;br /&gt;public class ImportDescriptor : System.Attribute{&lt;br /&gt;&lt;br /&gt;  /// &amp;lt;summary&amp;gt;&lt;br /&gt;  /// Custom Property Attribute&lt;br /&gt;  /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  /// &amp;lt;param name="displayName"&amp;gt;The string to be displayed in the Import UI (e.g. grid column) for this property.&lt;br /&gt;  /// &amp;lt;param name="required"&amp;gt;If true, a value for this property is required for import. If false, the property value is optional.&lt;br /&gt;  public ImportDescriptor(string displayName, string description, bool required) {&lt;br /&gt;      DisplayName = displayName;&lt;br /&gt;      Required = required;&lt;br /&gt;      Desc = description;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public string DisplayName{&lt;br /&gt;       get { return (_displayName); }&lt;br /&gt;       set { _displayName = value;  }&lt;br /&gt;  } private string _displayName = null;&lt;br /&gt;&lt;br /&gt;  public bool Required{&lt;br /&gt;      get { return (_required); }&lt;br /&gt;      set { _required = value;  }&lt;br /&gt;  } private bool _required = false;&lt;br /&gt;&lt;br /&gt;  public string Desc{&lt;br /&gt;      get { return (_desc); }&lt;br /&gt;      set { _desc = value; }&lt;br /&gt;  } private string _desc = null;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;As you can see we inherited from System.Attribute, and we are using an attribute called &lt;a href="http://msdn.microsoft.com/en-us/library/system.attributeusageattribute%28VS.80%29.aspx" target="_blank"&gt;System.AttributeUsage&lt;/a&gt; (msdn), that tells us how this attribute is going to be used.&lt;br /&gt;&lt;br /&gt;Now we need to add that attribute to the properties on our class that we expect to see in an import.  Assume we have a class Person that has properties of PersonID, FirstName, LastName, and Title.  And lets assume that everything except title is required.  So lets add the attributes to the Person class.&lt;pre&gt;&lt;br /&gt;public class Person {&lt;br /&gt;  private int _personID;&lt;br /&gt;  private string _first_name;&lt;br /&gt;  private string _last_name;&lt;br /&gt;  private string _title;&lt;br /&gt;&lt;br /&gt;  public Person() {&lt;br /&gt;      //empty constructor&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [ImportDescriptor("Person ID", "ID of the person", true)]&lt;br /&gt;  public int PersonID {&lt;br /&gt;      get { return _personID; }&lt;br /&gt;      set { _personID = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [ImportDescriptor("First Name", "First Name of the pesron.", true)]&lt;br /&gt;  public string FirstName {&lt;br /&gt;      get { return _first_name; }&lt;br /&gt;      set { _first_name = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [ImportDescriptor("Last Name", "Last Name of the person", true)]&lt;br /&gt;  public string LastName {&lt;br /&gt;      get { return _last_name; }&lt;br /&gt;      set { _last_name = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [ImportDescriptor("Title", "The persons title in the company (CEO, Developer, etc.)", false)]&lt;br /&gt;  public string Title {&lt;br /&gt;      get { return _title; }&lt;br /&gt;      set { _title = value; }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;We now have our class set up to use our attribute.  We can add more fields to our Person class and add the ImportDescriptor attribute and our code will automatically expect to see the field in the import.  So our framework is set up.  We now just need to consume this. Below is an example of how to use reflection to read the attribute, and handle the line in the import accordingly.  It is a brief example and will leave the rest of the import code as an exercise for you. In this example I am using reflection to read the attributes and store them in a class (ImportProperties) that we are using for the actual import.  The variable _dataType is of type Object.  I wanted this to be as generic as possible so that I could use this for any type of import, not just for the Person Class.&lt;pre&gt;&lt;br /&gt;private List&lt;importproperties&gt; GetAttributes(Object dataType) {&lt;br /&gt;  PropertyInfo[] props = dataType.GetType().GetProperties();&lt;br /&gt;  PropertyInfo prop;&lt;br /&gt;&lt;br /&gt;  List&amp;lt;importproperties&amp;gt; lst = new List&amp;lt;importproperties&amp;gt;();&lt;br /&gt;&lt;br /&gt;  for (int i = 0; i &amp;lt; props.GetLength(0); i++) {&lt;br /&gt;     prop = props[i];&lt;br /&gt;&lt;br /&gt;     if (prop.GetCustomAttributes(typeof(ImportDescriptor), false).Length &amp;gt; 0) {&lt;br /&gt;         ImportDescriptor importDesc = (ImportDescriptor)prop.GetCustomAttributes(typeof(ImportDescriptor), false).GetValue(0);&lt;br /&gt;&lt;br /&gt;         ImportProperties import = new ImportProperties();&lt;br /&gt;&lt;br /&gt;         import.DisplayName = importDesc .DisplayName;&lt;br /&gt;         import.Desc= importDesc.Desc;&lt;br /&gt;         import.Required = importDesc .Required;&lt;br /&gt;         lst.Add(import);&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return lst;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since you can have multiple attributes per target we are only going to be looking for the ImportDescriptor, you can extend this to read all attributes.&lt;br /&gt;&lt;br /&gt;Also, since this is using reflection and a list, you need to make sure you are using System.Reflection, and System.Collections.Generic in order to use PropretyInfo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2001596959660547368?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2001596959660547368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/09/custom-attributes-in-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2001596959660547368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2001596959660547368'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/09/custom-attributes-in-c.html' title='Custom Attributes in C#'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-8344863338692376542</id><published>2009-08-18T09:36:00.003-04:00</published><updated>2009-08-18T09:54:41.354-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>CHAMPIONS!!</title><content type='html'>&amp;lt;Trumpet Flair&amp;gt;&lt;br /&gt;&lt;br /&gt;Last night were the playoffs for Bottom of the Fifth.  It was a single elimination tourney, and our first game was at 8 against Commonwealth Chapel.  This is the team that has beat us twice, and seeded number 3 in the league.  Since we were seeded number 2 we were home team.&lt;br /&gt;&lt;br /&gt;The first inning they scored 1 quick run and we held them there for the next 3 innings.  We were nervous this first inning and we bobbled a few there, but we held them once we settled down.  Our offense though was much more productive than theirs.  And we rolled over on them for the rest of the game.  I think our biggest motivation to win this game was so we could go on to the finals and kick the crap out of Big League Chew.&lt;br /&gt;&lt;br /&gt;We got a 10 minute break between our first game and the second, and we were under way.&lt;br /&gt;&lt;br /&gt;Big League Chew was seeded number one at this point, and they we had beat them 2 out of the 3 times we went against them, and they are just all around annoying.  So we really really really wanted to cream them.  And we did.  Both teams came out swinging.  We were away this round so we were at bat first and put up a quick 5 runs.  We were consistent and had an awesome day both pitching and batting and quickly moved up 15-2.  They were ecstatic at every play of theirs, even going so far as calling out our players, asking them if they were ready.  They were loud and vocal, and pretty annoying.&lt;br /&gt;&lt;br /&gt;So since we were up by so much we flip flopped the last inning (as I have mentioned I am not a big fan of this).  So score is still 15-2, and they are up at bat again.  We get a strike out and a fly out to left field.  2 outs in the last inning.  And we get real nervous just thinking too much ("Get out of your head Crash"). And they get a rally going.  Again being really annoying and boastful after every hit.  But it doesn't matter, cause we still won in the end.  Final score was 15-13.&lt;br /&gt;&lt;br /&gt;Hopefully the Fifth will be playing some fall ball, but that is still up in the air, have to make sure we have enough players.&lt;br /&gt;&lt;br /&gt;But for now we are the reigning CHAMPIONS!&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.tombecker.net/images/champs.jpg" alt="team shot" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-8344863338692376542?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/8344863338692376542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/08/champions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8344863338692376542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8344863338692376542'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/08/champions.html' title='CHAMPIONS!!'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-5672260046785265978</id><published>2009-08-11T11:07:00.003-04:00</published><updated>2009-08-11T11:20:34.798-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>The Pros</title><content type='html'>So this was the very last game of our regular season.  Next week we have play offs and then we are off for a few weeks before fall ball (assuming we can get a team together).&lt;br /&gt;&lt;br /&gt;Last nights game against the Pros was an interesting one.  We were supposed to have two games yesterday but the first team we were supposed to play had to forfeit since they couldn't field a team.  So apparently the commissioner of the league thought that we were going to forfeit our second game for some reason, and told the ump for our field as well as the Pros that we weren't going to be there.&lt;br /&gt;&lt;br /&gt;So we get there with no umpire and the Pros leaving the field.  We get everything squared away and find an umpire that was hanging around getting ready for a late game and we can finally start the game.&lt;br /&gt;&lt;br /&gt;We were the home team, so we were out in the field first and the Pros came out swinging scoring 4 in the first inning.  It should have been 3, but I bobbled a pop fly that landed foul, but I should have had anyway.  It was in my glove, but it popped back out.  Bummer, but we got out of the inning not to much longer after that.  Bottom of the first we scored 3.&lt;br /&gt;&lt;br /&gt;We rallied a few innings later and put some runs up making the score 13-4.  It was about this time that our pitcher Craig took a line drive to the family jewels, and amazingly still made the out at first.  It was fantastic.  Such dedication, such grit.  Needless to say he sat out for a few innings icing down the goods. &lt;br /&gt;&lt;br /&gt;So we had to pull in our second string pitcher, Will, who did fine the first inning he pitched with some good fielding we held them that inning.  We are up and score one or two runs maybe.  I walked a few times, and we were sitting pretty.&lt;br /&gt;&lt;br /&gt;The next inning (the fifth I believe) Will is pitching again, and just keeps walking people.  They score 7 before Will throws in the towel.  And amazingly Craig comes back in to finish the game.  He closed out that inning and pitched one more striking out the go ahead run in the sixth.&lt;br /&gt;&lt;br /&gt;It was a rollercoaster of a game, but it was a good one.  I think everyone played very well, but Craig is the MVP of the game.  The only pitcher I know to start, leave the game, and come in to earn save.&lt;br /&gt;&lt;br /&gt;Next week are playoffs, and I'll let everyone know how we did.  Crossing our fingers for the campionship!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-5672260046785265978?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/5672260046785265978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/08/pros.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/5672260046785265978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/5672260046785265978'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/08/pros.html' title='The Pros'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-8206902217543945675</id><published>2009-08-07T11:10:00.003-04:00</published><updated>2009-08-07T11:22:07.611-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>Fighting Cox round 2ish</title><content type='html'>Last two weeks have been rained out so it has been a while since we've had a game, but we came back from the break strong and won what would normally be our last game of the regular season. &lt;br /&gt;&lt;br /&gt;It is usually pretty fun to play these guys.   They are a team from the local radio station and are a good group.  They were getting pretty frustrated with us though since we were taking so many of their pitches and we just kept walking around the bases.  I think I was up 3 times, and walked twice, and the ball I hit was low and outside (practicing my golf swing).  So there was some grumbling on their end this game, but I think we still had fun.&lt;br /&gt;&lt;br /&gt;I don't have the score but I do know we were up 15-2 in the second inning, if that tells you anything.&lt;br /&gt;&lt;br /&gt;Next week we have a double header, we are playing the two teams we missed playing the past two weeks, and then after that we are in the playoffs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-8206902217543945675?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/8206902217543945675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/08/fighting-cox-round-2ish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8206902217543945675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8206902217543945675'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/08/fighting-cox-round-2ish.html' title='Fighting Cox round 2ish'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-3796193435233570823</id><published>2009-08-07T11:02:00.002-04:00</published><updated>2009-08-07T11:07:44.895-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Token startelement in state epilog would result in an invalid xml document.</title><content type='html'>I was creating an XML document and kept running into this same error over and over again.  It seems that it is the default error for any sort of syntax problem with your XML documents.  So I would venture to guess that there are lots of ways of fixing it, but what worked for me was pretty simple (as most syntax errors are).  I didn't have a root element.  So make sure you always have a root or else!  &lt;br /&gt;&lt;br /&gt;See below for my code for writing an XML Doc&lt;pre&gt;  &lt;br /&gt;  string filepath = GetPath("myXML.xml"); //get full path&lt;br /&gt;&lt;br /&gt;  xmlTextWriter writer = new XmlTextWriter(filepath, null);&lt;br /&gt;&lt;br /&gt;  writer.WriteStartDocument();&lt;br /&gt;  writer.WriteStartElement("root"); //must have!!!!&lt;br /&gt;&lt;br /&gt;  foreach (Person p in myPeeps) {&lt;br /&gt;     writer.WriteStartElement("person");&lt;br /&gt;&lt;br /&gt;     writer.WriteStartElement("name");&lt;br /&gt;     writer.WriteString(p.Name);&lt;br /&gt;     writer.WriteEndElement();&lt;br /&gt;&lt;br /&gt;     writer.WriteStartElement("address");&lt;br /&gt;     writer.WriteString(p.address);&lt;br /&gt;     writer.WriteEndElement();&lt;br /&gt;&lt;br /&gt;     writer.WriteStartElement("title");&lt;br /&gt;     writer.WriteString(p.Title);&lt;br /&gt;     writer.WriteEndElement();&lt;br /&gt;&lt;br /&gt;     writer.WriteStartElement("age");&lt;br /&gt;     writer.WriteString(p.age);&lt;br /&gt;     writer.WriteEndElement();&lt;br /&gt;&lt;br /&gt;     writer.WriteEndElement();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   writer.WriteEndElement();&lt;br /&gt;   writer.WriteEndDocument();&lt;br /&gt;   writer.Flush();&lt;br /&gt;   writer.Close();  &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-3796193435233570823?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/3796193435233570823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/08/token-startelement-in-state-epilog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3796193435233570823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3796193435233570823'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/08/token-startelement-in-state-epilog.html' title='Token startelement in state epilog would result in an invalid xml document.'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2510812356299714054</id><published>2009-07-09T12:00:00.005-04:00</published><updated>2009-07-09T12:05:08.659-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>Big League Chew, the Slaughter</title><content type='html'>I've been late this week posting about the game because it just has been to depressing.  We lost...horribly.&lt;br /&gt;&lt;br /&gt;This is only our second loss of the season, and I think we are still on top, but a little sad none the less, especially since we won both of our previous games against them.  We couldn't put anything together batting, and our fielding was suspect at best.&lt;br /&gt;&lt;br /&gt;They just played a better game than us, and I'm going to leave it at that.  We play them at least one more and next time we will bring our 'A'-game to pop the Big League Chew bubble.&lt;br /&gt;&lt;br /&gt;Game next week is at 7:30 against Commonwealth Chapel (the only other team to beat us).  Wish us luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2510812356299714054?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2510812356299714054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/07/big-league-chew-slaughter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2510812356299714054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2510812356299714054'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/07/big-league-chew-slaughter.html' title='Big League Chew, the Slaughter'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-4094081209003499693</id><published>2009-07-01T09:40:00.005-04:00</published><updated>2009-07-01T09:58:40.938-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>The Pros, doubleheader</title><content type='html'>So this week, as I mentioned, we had a double header, and we won both games.  The first one we kinda rolled over on them, but the second one was quite the nail biter in the last inning.&lt;br /&gt;&lt;br /&gt;After the first inning I thought that we were going to just have a huge slug fest of a game.  They scored 3 runs very quickly the first inning, and we weren't fielding all that well at first.  I blame the sun, which was shining in the eyes of anyone to the right of second base.  But at the bottom of the first we scored 14 runs.  And that pretty much set the tone for the game. Their pitcher seemed a bit disheartened, and it is understandable we have been there before.  But they came back with 4 runs in the second, and held us pretty much for the rest of the game.  I think the final score was like 16-9 or something like that.&lt;br /&gt;&lt;br /&gt;The second game was a bit more interesting.  We didn't have that big first inning, and they came out swinging the second game.  They have some very big hitters on their team.  A few consistently hit it to deep deep left, which we aren't really used to in this league.  So the game went on with nothing all to interesting (other than my *HUGE* wiff, I ended up getting walked but it was a bad swing) till the last inning.  Since we were ahead by 5 they flipped the innings around so they batted twice in a row.  They do this to make the games shorter.  If they had come ahead we would have gotten our last at bat, so it is fair.  I'm not a huge fan of it, but whatever.&lt;br /&gt;&lt;br /&gt;They scored four runs in that last inning, and it was hard fought.  The go ahead run was at the plate, and our pitcher struck her out.  It was tense....full count and the whole nine yards.  Only thing that would have made it better would have been the bases loaded.&lt;br /&gt;&lt;br /&gt;Next week we have the late game (8:30) against Big League Chew.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-4094081209003499693?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/4094081209003499693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/07/pros-doubleheader.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4094081209003499693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4094081209003499693'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/07/pros-doubleheader.html' title='The Pros, doubleheader'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-3834980015318153938</id><published>2009-06-26T09:49:00.002-04:00</published><updated>2009-06-26T10:06:57.052-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Recursive Functions in SQL 2000</title><content type='html'>Recently I was asked for a list of all the history associated with a row in a database.  In this case when a row in the table was updated, we did an insert with the updates and updated the old row with a pointer to the new row.  We needed to do this so we could show history when needed without having to create a history table.&lt;br /&gt;&lt;br /&gt;So since I didn't know how many ancestors a row could have, I decided to use recursion.  And for those of you who never had a programming class with me know that I really don't like recursion, it confuses me.  But it had to be done.  So below is the recursive function that can be called to get a list of all ancestors of a given row:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE FUNCTION [dbo].[udf_GetAncestors] &lt;br /&gt;&lt;br /&gt;(@CurrID int)  &lt;br /&gt;&lt;br /&gt;RETURNS varchar(50)  AS  &lt;br /&gt;BEGIN &lt;br /&gt;&lt;br /&gt;DECLARE&lt;br /&gt;@ancestorIDs varchar(50),&lt;br /&gt;@NextID INT&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT  @NextID  = ItemID  &lt;br /&gt;FROM   Items&lt;br /&gt;WHERE RevisedItemID= @CurrID;&lt;br /&gt;&lt;br /&gt;SET @ancestorIDs = Convert(varchar, @CurrID);&lt;br /&gt;&lt;br /&gt;IF  @NextID IS NOT NULL BEGIN&lt;br /&gt;  SET @ancestorIDs = '''' + @ancestorIDs + ''', ' + dbo.udf_GetAncestors(@NextID);&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;Return @ancestorIDs &lt;br /&gt;&lt;br /&gt;END&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-3834980015318153938?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/3834980015318153938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/06/recursive-functions-in-sql-2000.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3834980015318153938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3834980015318153938'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/06/recursive-functions-in-sql-2000.html' title='Recursive Functions in SQL 2000'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2168479518355795793</id><published>2009-06-24T12:05:00.003-04:00</published><updated>2009-06-24T12:17:13.799-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>The Fighting Cox</title><content type='html'>This was the second time we have played this team ( didn't write about the first one), and both results were pretty much the same, a decisive victory for Bottom of the Fifth.&lt;br /&gt;&lt;br /&gt;The first inning though had us worried.  We were first at bat and we scored a few runs and we started off strong.  We get into the field and make some silly errors that put them in the lead.  An over throw to second sent the ball just off the dirt behind first base.  I run to get it and a hit that should have been held to a single with no one coming into home was converted to a triple and 1 or 2 runs came in.&lt;br /&gt;&lt;br /&gt;After the first inning though we got it together a bit.  Richie hit a grand slam, and I homered in my third at bat.  One of the best hitting nights we've had in a while.&lt;br /&gt;&lt;br /&gt;The funniest part of the game had to be our pitcher, Craig.  He was pitching well the entire game, but his fielding...well left something to be desired.  We had a large amount of slow dribblers go straight to him and for some reason he couldn't pick them up.   And when he did, his throws were not very accurate.  He threw one to me on first at my shoes, and one to third which went almost straight down and rolled over there.  Needless to say we didn't get the outs on that one.&lt;br /&gt;&lt;br /&gt;But despite a rough start and some crazy little fielding errors we won the game 12-5. &lt;br /&gt;&lt;br /&gt;Next week is a double header, but I'm not sure against who, since all these rain outs have messed with the schedule quite a bit.  I guess you'll just have to wait till next week to find out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2168479518355795793?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2168479518355795793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/06/fighting-cox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2168479518355795793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2168479518355795793'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/06/fighting-cox.html' title='The Fighting Cox'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-5289869511693555896</id><published>2009-06-12T11:39:00.002-04:00</published><updated>2009-06-12T11:59:09.510-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Extension Methods</title><content type='html'>So while running around playing with Linq, I just happened across &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx"&gt;another article&lt;/a&gt; by ScottGu, that talks about extension methods.  And I have decided that they are truly awesome.&lt;br /&gt;&lt;br /&gt;Extension methods allow you to add methods to existing types. In ScottGu's article he adds a called IsValidEmailAddress method to the string type.  I originally had great plans on using this in a project to add some extension methods to a base type so they would show up on all the children.  And then I realized that I could do the same thing by just writing the function in the base class instead.  Same result.  So the real use for these things are when you cannot modify the type definition.&lt;br /&gt;&lt;br /&gt;So below is the extension method that I originally was going to use.  It has all the syntax you need and it worked.  I just realized that it was overkill, however awesome it may be.  Lookup and LookupElement are parent classes for all of the lookup objects in the project.  Lookup is a list of lookupElements.&lt;br /&gt;&lt;pre&gt;public static string GetTextFromValue(this Lookups.Lookup L, int ID){&lt;br /&gt;     string text = "";&lt;br /&gt;     foreach (Lookups.LookupElement le in L) {&lt;br /&gt;         if (le.Value == ID){&lt;br /&gt;             text = le.Text;&lt;br /&gt;             break;&lt;br /&gt;         }             &lt;br /&gt;     }&lt;br /&gt;     return text;&lt;br /&gt; }&lt;/pre&gt;So after building this a new method would show up in IntelleSense when you used a Lookup object.  And you would use it just like you would a normal method call.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-5289869511693555896?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/5289869511693555896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/06/extension-methods.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/5289869511693555896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/5289869511693555896'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/06/extension-methods.html' title='Extension Methods'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-3991838959862523186</id><published>2009-06-12T09:33:00.006-04:00</published><updated>2009-06-12T10:16:46.517-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Linq, Lambda Expressions and Predicate Delegates</title><content type='html'>I have recently been giving the opportunity to play around a bit more with Linq and while playing around with that I have run into the related topics of Lambda Expressions and Predicates.   This post will be broken up into 3 sections (can we guess what they are?) and will just briefly provide an over view for each.&lt;br /&gt;&lt;h2&gt;Linq&lt;/h2&gt;Linq stands for language-integrated query, and it allows you to query your data sets in code instead of heading back to the database in order to get a subset, and without having to loop through code.  The syntax is very similar to SQL.&lt;br /&gt;&lt;br /&gt;For example lets say I had a list of people, and I wanted to pull back everyone who lived in Richmond.  Previously I would have to go back to the database and reselect my list of people or maybe loop through the list and do it that way.  But using Linq I can do this much easier.&lt;pre&gt;List&amp;lt;People&amp;gt; myPeeps = new List&amp;lt;People&amp;gt;();&lt;br /&gt;//Fill list&lt;br /&gt;var results = from p in myPeeps&lt;br /&gt;            where p.Location= "Richmond"&lt;br /&gt;            orderby p.Name&lt;br /&gt;            select p;&lt;br /&gt;&lt;/pre&gt;As you can see this syntax is very similar syntax to SQL.  You can now take the results and bind them a control, or do any sort of computations on it.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Lambda Expressions&lt;/h2&gt;Lambda Expressions are&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt; defined by MSDN &lt;/a&gt;as "...an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types."&lt;br /&gt;&lt;br /&gt;So what exactly that means I'm not to sure, but it makes it real easy to filter things out inline and simplifies the above Linq query a bit. Using the same situation above the query changes to&lt;pre&gt; myPeeps.Where(p =&gt; p.Location== "Richmond");&lt;/pre&gt;Pretty simple no?  It doesn't have all the same power as Linq since you can really order or use multiple criteria and the like, but it is very simple and easy to use.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Predicates Delegates&lt;/h2&gt;&lt;br /&gt;Predicates are &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bfcke1bz.aspx"&gt;defined as&lt;/a&gt; "...the method that defines a set of criteria and determines whether the specified object meets those criteria."  What that means is that you can define a function that returns a boolean to evaluate if your item in a list meets certain criteria.  Again using the above example, I define the actual predicate delegate.&lt;pre&gt;&lt;br /&gt; private bool IsRichmonder(People p) {&lt;br /&gt;    return p.Text == "Richmond";&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;And once that is done, I just pass the predicate into the select clause on my list.&lt;pre&gt;myPeeps.Select(IsRichmonder);&lt;/pre&gt;&lt;h2&gt;Summary&lt;/h2&gt;All of these examples have been pretty simple, but I hope you can see the power of all of these methods when properly leveraged.&lt;br /&gt;&lt;br /&gt;I relied on ScottGu's &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx"&gt;articles &lt;/a&gt;to learn about these and to write this post&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-3991838959862523186?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/3991838959862523186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/06/linq-lambda-expressions-and-predicates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3991838959862523186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3991838959862523186'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/06/linq-lambda-expressions-and-predicates.html' title='Linq, Lambda Expressions and Predicate Delegates'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2561821036867283068</id><published>2009-06-09T12:30:00.003-04:00</published><updated>2009-06-09T12:43:16.988-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>Payerpath</title><content type='html'>So I forgot to write about last weeks games, but we had a double header last week against Commonwealth Chapel.  We split the series 1-1.  Both games were very close the first game with us only losing by a single run.  Looking forward to playing them again as we are very closely matched.&lt;br /&gt;&lt;br /&gt;Yesterday we played Payerpath, a team we have played before.  We played well with very few errors fielding.  We also batted very well, with I think everyone getting on base at least once.  We won the game 15-2 I think, I don't have the score book here, and the Wife is no longer our scorekeeper so I don't have access to it. &lt;br /&gt;&lt;br /&gt;I must say that the very last play by Will was one to remember, and a good way to end the game.  Their batter hit a screamer between first and second base and he just reached out and snagged it.  It was a good play and a good way to end the game.  But I must say that the most interesting play of the game was when a batter from the other team hit a pop fly between homeplate and the pitcher's mound.  Both our catcher, Erika, and pitcher, Craig, run of the ball and neither of them call it.  So they both watch it hit the ground between them, when all either one of them had to do was reach out their glove.&lt;br /&gt;&lt;br /&gt;So like I said over all a very good game.  Next week Bottom of the Fifth will be playing "The Pros" at 7:30.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2561821036867283068?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2561821036867283068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/06/payerpath.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2561821036867283068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2561821036867283068'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/06/payerpath.html' title='Payerpath'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-2083012622227081849</id><published>2009-05-26T13:06:00.002-04:00</published><updated>2009-05-26T13:08:54.744-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Writing to a file with C#</title><content type='html'>It had been a while since I had to write a file with .Net, I don't think I really had done it since vanilla ASP.  As I remember it wasn't hard then and it really hasn't changed to much since then.  See below for code on how to check to see if the directory exists, and then how to actually create and write to a file.&lt;br /&gt;&lt;h4&gt;Check to see if path exists if not create it&lt;/h4&gt;&lt;pre&gt;if(!System.IO.Directory.Exists(path))&lt;br /&gt;    System.IO.Directory.CreateDirectory(path);&lt;/pre&gt;&lt;h4&gt;Create the file &lt;/h4&gt;&lt;pre&gt;&lt;br /&gt;public void WriteFile(string fileText, string fileName){&lt;br /&gt;       string fullPath = "&amp;lt;Where ever your path is&amp;gt;"&lt;br /&gt; &lt;br /&gt; try{&lt;br /&gt;   FileInfo file = new FileInfo(fullPath);&lt;br /&gt;&lt;br /&gt;   StreamWriter stream = file.CreateText();&lt;br /&gt;          stream.WriteLine(fileText);&lt;br /&gt;          stream.Close();&lt;br /&gt; }catch(Exception ex){&lt;br /&gt;   //handle exception&lt;br /&gt; }       &lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-2083012622227081849?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/2083012622227081849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/05/writing-to-file-with-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2083012622227081849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/2083012622227081849'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/05/writing-to-file-with-c.html' title='Writing to a file with C#'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-533186225885833357</id><published>2009-05-20T08:23:00.003-04:00</published><updated>2009-05-20T08:32:23.769-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>Big League Chew, round 2</title><content type='html'>So this game was kind of a nail bitter. It really did come right down to the wire with the winning run on first.  We ended up winning 12-9, but it was touch and go there in the last inning.&lt;br /&gt;&lt;br /&gt;We started off really well, we had a 10-0 lead coming out of the first inning, and then I don't know what happened we stopped hitting and they started. I really don't know how else to explain it.  I think there were a couple of iffy calls made by the umpire but that really doesn't explain us pissing away a 10-0 lead.  Personally I walked once (first inning) and grounded out in the second, and then we subbed me out before I could bat in the third.&lt;br /&gt;&lt;br /&gt;I think we got cocky and over confident with our lead and just started playing bad fundamentals.  We had some good plays with our shortstop and 3rd baseman snagging some line drives, but lets just say that if we had to play one more inning the outcome may have been a bit different&lt;br /&gt;&lt;br /&gt;No game next week because of Memorial day, but in two weeks we play The Pros.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-533186225885833357?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/533186225885833357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/05/big-league-chew-round-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/533186225885833357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/533186225885833357'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/05/big-league-chew-round-2.html' title='Big League Chew, round 2'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-4942136164510403991</id><published>2009-05-19T13:07:00.004-04:00</published><updated>2009-05-19T13:23:25.295-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Unable to attach debugger process in Visual Studio</title><content type='html'>Today I had to debug a web service that was running locally and in the same solution where the project that I am working on.  Before I seem to remember just automatically stepping into the web service while debugging, but that was in Visual Studio 2005, so it could be different with 2003.  So in order to do this you need to attach the worker process to the debugger so it can load all the symbols and whatnot, so it will catch at breakpoints and you can step through line by line&lt;br /&gt;&lt;br /&gt;So to attach a new process for the debugger to what you go to Debug -&gt; Processes and then choose from the list and click attach.  In my case this was the .Net worker process aspnet_wp.exe.  This did not work for me right off, and it seems that many other people are having the same problem.  I kept getting that wonderfully generic MS message that says "Unable to attach process" and that was it, no other help.  In this case it can be just a simple oversight.&lt;br /&gt;&lt;br /&gt;There is a worker process for each version of .Net that you have running.  I was careless when I set up the web service in IIS and I had it running under the 2.0 worker process instead of 1.1, which is fine in general since everything is backwards compatible, but in order to debug you need to make sure you have everything matching up and choosing the right worker process for your app.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-4942136164510403991?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/4942136164510403991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/05/unable-to-attach-debugger-process-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4942136164510403991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4942136164510403991'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/05/unable-to-attach-debugger-process-in.html' title='Unable to attach debugger process in Visual Studio'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-3442687117583511948</id><published>2009-05-14T15:09:00.003-04:00</published><updated>2009-05-14T15:13:07.765-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random'/><title type='text'>Been gone for a while</title><content type='html'>I know I have been gone for a while, and haven't been posting very much, but I promise I am still out here.  I have been really busy the past month or so.  Getting married, buying a house, and all that.  Still don't have internet at the house yet, that is why there hasn't been any softball postings (we are 4-0 I think, whoohoo).  And I have been on the bench since the first of the year, and that is why there hasn't been any .Net or SQL postings.  But that, hopefully, will change soon as I have started on a new contract.&lt;br /&gt;&lt;br /&gt;I am now working for Intrepid Services here in Richmond, and will be working on some cool projects, so once I get into those I will start posting some code up here again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-3442687117583511948?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/3442687117583511948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/05/been-gone-for-while.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3442687117583511948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/3442687117583511948'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/05/been-gone-for-while.html' title='Been gone for a while'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-601619861117002518</id><published>2009-04-14T08:48:00.004-04:00</published><updated>2009-04-15T12:21:48.772-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Softball'/><title type='text'>Big League Chew</title><content type='html'>So it is that time of the year again, softball season has started!  This year I am only playing on team (Bottom of the Fifth) up in Richmond.  And there have also been a few changes.  For example we are no longer playing double headers, there are unlimited home runs (which worked out well for us last night), and and we moved down to a lower league instead of the really high league like last year.&lt;br /&gt;&lt;br /&gt;So yesterday we played Big League Chew, and it was a great opening day for us.  We won the game 11-9 I think, I don't have to the score book around here. &lt;br /&gt;&lt;br /&gt;We had our usual crowd out there, but we were down one girl, so we had to take an auto out at the end of our lineup, but it didn't seem to hinder us too bad.  Everyone hit real well last night with 4 home runs, 2 from Aaron, 1 from Richie and 1 from me.  So hopefully we can keep that trend going. &lt;br /&gt;&lt;br /&gt;Our defense was pretty good last night as well, just a few small errors and a couple bad hops down the third base line.  The one that sticks out in my mind was the last inning, when our team captain Will came into left field, we were up 5 and just had to hold them to get the win.  High fly ball out between left and center, both fielders running, Will almost has it and then slips in the grass and lays down in the outfield, they come in for a home run on that one.&lt;br /&gt;&lt;br /&gt;I will be missing next week's game because I'll be on my honeymoon.  But I'll be back in two weeks against PayerPath.&lt;br /&gt;&lt;br /&gt;Oh yea, and check out our &lt;a href="http://softball.net/pdf/2009richmondschedules/2009%20Dominion%20Co-Rec.pdf" target="_blank"&gt;schedule&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-601619861117002518?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/601619861117002518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/04/big-league-chew.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/601619861117002518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/601619861117002518'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/04/big-league-chew.html' title='Big League Chew'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-1847125386992748554</id><published>2009-01-14T20:02:00.004-05:00</published><updated>2009-01-14T20:25:50.508-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Rendering an Image from a blob using an httpHandler</title><content type='html'>So I've written before on how to &lt;a href="http://www.tombecker.net/2008/01/uploading-file-into-oracle-blob.html" target="_blank"&gt;upload a file to a blob in Oracle&lt;/a&gt;, but I haven't written about how to retrieve it.  In this post I am specifically talking about images in this post but you can change out the MIME type and it would work the same.&lt;br /&gt;&lt;br /&gt;I am going to show you how to use an IHTTPHandler in order to show your image.  I used &lt;a href="http://stackoverflow.com/questions/21877/dynamically-rendering-aspimage-from-blob-entry-in-asp-net" target="_blank"&gt;this &lt;/a&gt;for reference.&lt;br /&gt;&lt;br /&gt;So add to your project a new generic handler.  It will pre-populate a few methods,  and basically you just add to them.  See my code below&lt;pre&gt;&lt;br /&gt;Public Class ImageHandler&lt;br /&gt;   Implements System.Web.IHttpHandler&lt;br /&gt;&lt;br /&gt;   Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest&lt;br /&gt;       If context.Request.QueryString("id") IsNot Nothing Then&lt;br /&gt;           Dim id As Integer = CInt(context.Request.QueryString("id"))&lt;br /&gt;           Dim blob As Byte()&lt;br /&gt;           blob = getImage(id)&lt;br /&gt;           If blob IsNot Nothing Then&lt;br /&gt;               context.Response.Clear()&lt;br /&gt;               context.Response.ContentType = "image/pjpeg"&lt;br /&gt;               context.Response.BinaryWrite(blob)&lt;br /&gt;               context.Response.End()&lt;br /&gt;           End If&lt;br /&gt;       End If&lt;br /&gt;   End Sub&lt;br /&gt;&lt;br /&gt;   ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable&lt;br /&gt;       Get&lt;br /&gt;           Return True&lt;br /&gt;       End Get&lt;br /&gt;   End Property&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   Private Function getImage(ByVal ID As Integer) As Byte()&lt;br /&gt;       'Select blob from the db&lt;br /&gt;   End Function&lt;br /&gt;End Class&lt;br /&gt;&lt;/pre&gt;So after you have added this to your project you are ready to use it.  There are many ways to do this, but I used an .Net image control.  Either in the code behind or at design time, I defined the URL in the code behind when I bound the rest of the stuff on my page, but basically all you to have to do is link to the HttpHandler, and give it a query string with the ID you want. Example below&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    Me.imgProductImage.ImageUrl = "~/imagehandler.ashx?id=" &amp; D&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-1847125386992748554?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/1847125386992748554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2009/01/rendering-image-from-blob-using.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1847125386992748554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1847125386992748554'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2009/01/rendering-image-from-blob-using.html' title='Rendering an Image from a blob using an httpHandler'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-1279013167168929057</id><published>2008-12-23T08:35:00.004-05:00</published><updated>2009-04-05T22:20:25.035-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>.Net Resource Files</title><content type='html'>Resource files in .Net will allow you to create customized values for either different languages or if you are using an the same app for multiple people on different servers, you can store things like titles, names, and other specific version info that you don't want to hard code.&lt;br /&gt;&lt;br /&gt;You can store the resource file (resx) in either the App_GlobalResources or the App_LocalResources folder depending on the scope of the resource.&lt;br /&gt;&lt;br /&gt;The values in the resource file are stored as XML as key/value pairs.  Pretty easy stuff, and you can store pictures, text, icons, or audio...anything really in here.&lt;br /&gt;&lt;br /&gt;To get things out of the resource file you can either bind it to a label (or any other bindable control)&lt;br /&gt;&lt;pre&gt;&amp;lt;asp:label id="label1" text="'&amp;lt;%$resources:ClassName,Property"&amp;gt;' runat="Server" /&amp;gt;&lt;/pre&gt;Where ClassName is the name of the resource file without the .resx extension on it, and Property is the key.&lt;br /&gt;&lt;br /&gt;Or if you wan to access the key value pair programmatically you can access a global resource by using this&lt;pre&gt;HttpContext.GetGlobalResourceObject("ClassName", "Property")&lt;/pre&gt;or you can access a local resource by using&lt;pre&gt;HttpContext.GetLocalResourceObject("virpath", "Property")&lt;/pre&gt;where you pass in the virtual path of the local resource object.&lt;br /&gt;&lt;br /&gt;I used &lt;a href="http://msdn.microsoft.com/en-us/library/ms227982.aspx" target="_blank"&gt;these&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ms227427.aspx" target="_blank"&gt;two&lt;/a&gt; articles as reference&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-1279013167168929057?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/1279013167168929057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2008/12/net-resource-files.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1279013167168929057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/1279013167168929057'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2008/12/net-resource-files.html' title='.Net Resource Files'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-6709814448679916055</id><published>2008-12-16T15:32:00.004-05:00</published><updated>2008-12-16T15:42:37.305-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Visual Studio Tips: Task List Comments</title><content type='html'>I don't know about a lot of you but when I code sometimes I will leave this on a page to come back and do later, or I have some hack that I am using temporarily that I am going to need to come back and change.  I am a bit scatter brained and sometimes I forget to come back and fix these.&lt;br /&gt;&lt;br /&gt;That is why when I'm working through these I leave myself notes, in the Visual Studio task list.  You can manually type things in there or you get things in there directly from your code comments by using comment tokens.&lt;br /&gt;&lt;br /&gt;There are a few built in (TODO, HACK, and UNDONE)  that I use all the time, but you can&lt;a href="http://msdn.microsoft.com/en-us/library/zce12xx2%28VS.80%29.aspx"&gt; add your own&lt;/a&gt;, or just use the built in ones by just adding the prefix in front of your comment. ex:&lt;div class="codeBlock"&gt;&lt;br /&gt;'TODO: find more elegant solution&lt;br /&gt;'HACK: hardcoded&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;These will show up for you to come back to in your task list so you don't have to go searching around double click the task and away you go.   A big time saver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-6709814448679916055?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/6709814448679916055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2008/12/visual-studio-tips-task-list-comments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/6709814448679916055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/6709814448679916055'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2008/12/visual-studio-tips-task-list-comments.html' title='Visual Studio Tips: Task List Comments'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-4103868614364560004</id><published>2008-12-16T11:05:00.004-05:00</published><updated>2008-12-16T11:20:49.334-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Deciphering IE Release Numbers</title><content type='html'>So I am researching a very weird issue for my app.  And it led me to having to decipher &lt;acronym title="Internet Explorer"&gt;IE&lt;/acronym&gt; release numbers.&lt;br /&gt;&lt;br /&gt;So my release (or version) number is: 6.0.2900.2180.xpsp_sp2_gdr.080814-1233.  I'll break it down bit by bit.&lt;ul&gt;&lt;li&gt;&lt;strong&gt;6.0.2900.2180&lt;/strong&gt; is the build number, check &lt;a href="http://support.microsoft.com/kb/164539"&gt;here&lt;/a&gt; for a full list.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;xpsp_sp2_gdr&lt;/strong&gt; stands for Windows XP sp2, and not to sure what the gdr stands for, and can't really find a good answer out in the internet&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;080814 &lt;/strong&gt;is August 14, 2008, so it is YYMMDD date format (the part i was interested in)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;1233 &lt;/strong&gt;is a mystery to me, much like the gdr.&lt;/li&gt;&lt;/ul&gt;So that's the release version.  Some parts are unknown to me, but at least I know a little bit more and it helped me figure out my user's error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-4103868614364560004?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/4103868614364560004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2008/12/deciphering-ie-release-numbers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4103868614364560004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/4103868614364560004'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2008/12/deciphering-ie-release-numbers.html' title='Deciphering IE Release Numbers'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3887765047062401926.post-8793433690866878375</id><published>2008-12-03T07:32:00.002-05:00</published><updated>2008-12-03T07:38:29.302-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Max versus Greatest in Oracle</title><content type='html'>So I was trying to figure out the greatest of three dates in oracle.  They were coming from 3 different columns across three different tables.  So I figured I could do something like the following&lt;br /&gt;&lt;pre&gt;SELECT MAX(A.date, B.date, C.date) FROM. . .etc&lt;/pre&gt;&lt;br /&gt;But apparently that doesn't work.  The max function will not work across multiple columns.  That's when I learned about the greatest function.  Does the same thing as max, but lets you do it across multiple columns.  The above query became&lt;br /&gt;&lt;pre&gt;SELECT GREATEST(A.date, B.date, C.date) FROM . . .etc.&lt;/pre&gt;&lt;br /&gt;So, Max = one column, Greatest = multiple columns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3887765047062401926-8793433690866878375?l=www.tombecker.net%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/8793433690866878375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.tombecker.net/2008/12/max-versus-greatest-in-oracle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8793433690866878375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3887765047062401926/posts/default/8793433690866878375'/><link rel='alternate' type='text/html' href='http://www.tombecker.net/2008/12/max-versus-greatest-in-oracle.html' title='Max versus Greatest in Oracle'/><author><name>Tom Becker</name><uri>http://www.blogger.com/profile/16822988871836198898</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='03266632363545066746'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>