Tuesday, November 23, 2004
When talking with Carl & Rory about INETA on DotNetRocks last Friday, I mentioned (not for the first time) the amazing explosion of .NET in LATAM. It always surprises me. Here is a perfect example for a blog post today.

Posted from BLInk!
Tuesday, November 23, 2004 2:03:14 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Larry O'Brien puts his finger right on it!

Casey Chesnut, who’s my favorite Tablet PC programmer because he does all this stuff apparently without realizing that it’s supposed to be hard,....



Posted from BLInk!
Tuesday, November 23, 2004 1:45:48 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Flipping through a recent issue of Visual Studio Magazine, I see not one but two pictures of the ever fun-loving Shervin Shakibi, an INETA guy and user group leader in Florida. Of course, that would be due to the fact that the article was written by Jason Beres! What a hoot. Hi Sherv!



Posted from BLInk!
Tuesday, November 23, 2004 12:24:32 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Through INETA, I get the thrill of seeing .NET user groups popping up all over the world. Here is Michal Chaniewski, a .NET developer in Poland who is not only translating a 900 page ASP.NET book into Polish, but just won 2nd place in a .NET competition held by Microsoft Poland. Congrats Michal! I have roots in Poland, so this stuff definitely catches my eye!



Posted from BLInk!
Tuesday, November 23, 2004 11:55:37 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Raymond Chen explains why folders like My Pictures would reappear after you delete them.

There's actually something that caught me by surprise in .NET that I learned to accept that is along the same lines. I have some code that needs to look for a file in the Application Data folder area for a particular program. But I don't want to use the CommonAppDataPath, as this creates a new folder for each version of the application. Therefore, I use the GetParent function combined with the folder name I always want to use like this:

dirStore = System.IO.Directory.GetParent(System.Windows.Forms.Application.CommonAppDataPath).ToString & "\filestore"

But this actually creates the CommAppDataPath folder anyway! Maybe there's an overload I'm missing and I learned to accept it. My data goes where I want it to in the long run and the users never look there anyway.

 



Posted from BLInk!
Tuesday, November 23, 2004 10:31:07 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
800Response has a Web Developer job listed in www.sevendaysvt.com. They don't have the job listed on their website (that I can find). The job descrip says "must be familiarl with Dreamweaver, Fireworks and Flash, and have excellent system architecture and application/database design skills." There's more. If you can't find 7Days, maybe email blesperance@800reponse.com for a job description.

Posted from BLInk!
Tuesday, November 23, 2004 9:34:52 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
The Flynn Center in Burlington is looking for a Systems Support person. The job description mentions things like writing SQL Stored Procedures, mainting Exchange Server, some MacOXS knowledge and more.

Posted from BLInk!
Tuesday, November 23, 2004 9:30:35 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
WSE
Tuesday, November 23, 2004 9:01:59 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
and it looks like it's on Community Server! Stuart is pretty well known and very involved in the .NET community in the PacNorthWest area, so we tricked him into being the INETA liaison for all of the INETA groups in Washington, Idaho and Oregon (where he is).

Posted from BLInk!
Tuesday, November 23, 2004 7:40:37 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Monday, November 22, 2004

BulkCopy sounds great on paper, but have you actually tried it?

I did. I took a 104,000 record table from SQL2000 on one server and used BulkCopy to import those records into a pre-existing table in SQL2005 on another server.

But first I tried the same operation with DTS as a benchmark and that took 21 seconds. (note that I'm doing this on an older computer that is 700 mhz and I think 512MB Ram. The remote server is an old dog, too.)

Then I wanted to see what it was like in code without bulk copy. I thought I would at least leverage some of the new features in ADO.NET 2.0 for this. I grabbed the same 104,000 records into a DataReader and used DataTable.Load (new feature in ado.net 2.0) to pull it into a DataTable. Then rather than let a DataAdapter.Update insert this one at a time (puh-lease!), I leveraged the new batch capabilities.  SQLServer did not like 1000 records at a time (too many parameters in one execute command) so I set UpdateBatchSize to 100. I also am using the beautifully simple little System.Diagnostics.StopWatch class in this test. It's been running a while. I will come back and insert the time here when it finishes > 41 minutes <. If the lights start dimming in Burlington, you'll know why!

Before this test though I did the same operation using BulkCopy. Again, I pulled the 104,000 records from the remote server (on the same hardwired network) into a datareader and then passed that datareader into a SqlBulkCopy object, then called it's WritetoServer method.

So remember the DTS took 21 seconds. How long did the operation take in ADO.NET 2.0?

Let's have a few guesses and then I'll tell you. Heh heh heh.

OKAY - it was 23 seconds! Basically the same as the DTS! Rather than 180 times as long as with the batch updating which would have been impossible with ADO.NET 1.1 where there is no batch updating. So that may have been 100 times longer than the batch update way.


Posted from BLInk!

Monday, November 22, 2004 9:59:25 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Hervey had to listen to me whine about this one. I have a remote web server and could not create policy files from the settings tool.

"The Security Settings Wizard can support creating Policy files for remote service."

thanks! It's minor, but helpful.

A quick perusal of the readme which Hervey Wilson has on his blog, shows some helpful stuff with X509 tokens (like friendly names) some help with managing custom security tokens

ok ok back to my ado.net 2.0 now



Posted from BLInk!
WSE
Monday, November 22, 2004 9:38:30 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
I haven't even read Hervey's post yet! (and booo hooo I'm buried in ADO.NET 2.0 perf tests at the moment) but here is what's new in this pre-release which can be downloaded and checked out.

Posted from BLInk!
WSE
Monday, November 22, 2004 9:33:14 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
and Code Magazine's Rod Paddock gets the scoop!

Posted from BLInk!
Monday, November 22, 2004 7:43:52 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
JUST KIDDING!

Posted from BLInk!
Monday, November 22, 2004 5:05:49 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

this is the BEST ! Hooray!! Great great idea folks!!!

http://armyadvice.org/armysteve/archive/2004/11/22/932.aspx

I know people have sent Steve movies (Russ!) , candy and stuff to give out to kids (Rob!).



Posted from BLInk!
Monday, November 22, 2004 3:07:47 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Well, it's really hard to follow recent deeply technical shows with the likes of Juval Lowy, Jay Roxe, Kate Gregory, and a show with Mark Pollack, Ted Neward and Don Box, but heck "I yam who I yam" and hopefully it'll be a fun show to listen to and you'll even learn something new that's actually technical.

As we are supposedly our own worst critics....I hope that's truly the case here. :-)

Thanks Carl for inviting me on.

okay okay here's the link



Posted from BLInk!
Monday, November 22, 2004 9:25:42 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
As "rizzo" points out, my astonishment re: wrapping a SQL excution inside the new System.Transactions.TransactionScope in .NET 2.0 isn't 100% a new concept. If you used Enterprise Services (which I never ever had need to so I don't know jack about them) which is in the namespace SystemEnterpriseServices, you know that some of this ability existed in .NET 1.1 for anyone doing distributed transactions. The new stuff is improved greatly over the old which I can tell from reading the documentation but I can tell even more from reading the excitement of developers like Bill Ryan  and Sahil Malik who did use the transactions in Enterprise Services.

Posted from BLInk!
Monday, November 22, 2004 9:06:08 AM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 
 Sunday, November 21, 2004
My eyes are getting bigger and bigger as I'm digging into transactions in ADO.NET 2.0, or I should really just say in .NET 2.0.

First, I like that it solves a problem I currently have with a .NET 1.1 application.

I have to insert data into two tables. The first gets one new record, the second gets many that are related to the first.. If the first insert works, I go the second. If one of the updates to the 2nd table update fails, I have to roll back all that were done before it and then I have to delete the new record out of the first table. There may be a better way in 1.x, but that's the best I could figure out.

Now with MARS, I can use one connection and therefore one transaction on all of these executions. A failure in the 2nd set will also rollback the first. That is super sweet.

In fact, Angel Saenz-Badillos recommends this as one of the two reasons *he* would use MARS.

Now I find this great 15 seconds article by Bill Ryan who has also found a wonderful muse in the aptly named Angel . Though I was experimenting with transactions using the same old way (using the SqlTransaction class), Bill shows a much simpler implementation using the new System.Transactions.TransactionScope class. (The namespace is new and I cannot believe I don't have this (yet) in my Whidbey BCL presentation!!!) Oh boy! First of all, if you can remember the first time you tried to implement a transaction in ADO.NET, it was really confusing (and remains so). This implementation, wrapping the whole thing inside of a transaction (very new stuff for me) is really simple!

Think about what's happening here, I'm using System.Transactions.TransactionScope - nothing to do with SQL, but it's rolling back or committing my SQL transactions!  I have coded this up with two commands on one connections. Here's some VB:

    Public Sub MARSUpdateTestTrans()
        Dim sqlbuilder As New SqlConnectionStringBuilder
        With sqlbuilder
            .ConnectionString = GetSqlString()
            .MultipleActiveResultSets = True
        End With
        Using ts As New System.Transactions.TransactionScope
            Dim IsConsistent As Boolean = False
            Dim conn As New SqlConnection(sqlbuilder.ToString)
            Dim cmd1 As New SqlCommand("update employee set fname='Julie' where emp_id='KJJ92907F'", conn)
            Dim cmd2 As New SqlCommand("update employee set fname='Annabelle' where emp_id='AMD15433F'", conn)
            conn.Open()
            Try
                cmd1.ExecuteReaderExecuteNonQuery 'oops this had started out as a query...forgot to change the method
                cmd2.ExecuteNonQuery
                Throw New Exception
                IsConsistent = True
            Catch ex As Exception
                 'whatever else you want to do
            Finally
                ts.Consistent = IsConsistent
                conn.Close()
            End Try
        End Using
    End Sub

If that's not enough, Bill explains that you can wrap calls to totally different  databases inside of this one transaction and it handles all of the goo for you.

As if that isn't enough, Bill goes on (with some encouragement from Angel) to explain something that is beyond the scope of work I have done, but this is what thrills him even more. Not only can the transactionscope handle the different databases, but it also knows how to deal with local and distributed, SQL Server, Oracle, MSMQ.

Do not ignore this class. No, it won't solve world hunger. But maybe you can go do some community service work with all of your free time it just gave you!

So remember, the SqlTransaction class is still there and there may be lots of cases where it's better to use (one case is for more control about how the commits and rollbacks work). There is still more to explore!



Posted from BLInk!
Sunday, November 21, 2004 9:29:07 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

Sahil (who is the author of this book on ADO.NET) and I chatted about transactions in MARS after my DotNetRocks show on Friday. I think his curiousity lay in the potential of multiple transactions within one connection in MARS. Rather than theorize, I thought I would just try it in code and my answer is "can't be done". You will get a System.InvalidOperation Exception that says "SqlConnection does not support parallel transactions."

In theory this makes sense. In his MARS FAQ post, Angel (a tester on the ADO.NET team) explains when he likes to leverage MARS:

Q: So if MARS is not for performance what is it good for?

A: I like to use MARS in two core scenarios, 1) When using MARS results in cleaner looking code and 2) when I am using Transactions and need to execute in the same isolation level scope.

Q: When does using MARS result in cleaner looking code?

A: The quintessential MARS example involves getting a datareader from the server and issuing insert/delete/update statements to the database as you process the reader.

 Also, it's good to note that MARS just is, it's just there. You don't really turn it on or off (though you can change the SQLConnection setting - but definitely read the FAQ on that point). It just kicks in when needed. It lets us code in a way that is logical. MARS was one of the most requested features for ADO.NET 2.0. It was really hard to get in there, but people were tired of getting an error message when they did what came naturally, try to use one connection for multiple commands.

But MARS won't prevent you from writing code that will reduce your performance. In many cases, you will actually have much better performance leveraging connection pooling over forcing multiple queries (or executes) on one connection. So you should definitely consider how you take advantage of this feature.



Posted from BLInk!
Sunday, November 21, 2004 9:17:22 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  | 

You've got to love this level of detail! Here is an exception raised from SQL Server 2005 into VS2005 (latest CTP) when I was doing some testing to play with transactions in MARS and passing in some tsql to do a table update.



Posted from BLInk!
Sunday, November 21, 2004 4:54:52 PM (Eastern Standard Time, UTC-05:00)  #     |  Comments [0]  |