Tuesday, December 27, 2011

RowVersion

http://msdn.microsoft.com/en-us/library/ms182776.aspx
"You can use the rowversion column of a row to easily determine whether any value in the row has changed since the last time it was read. If any change is made to the row, the rowversion value is updated. If no change is made to the row, the rowversion value is the same as when it was previously read. To return the current rowversion value for a database, use @@DBTS."


So what? Rowversion allows you to use more intelligent methods to choose which data to send to a user. This is a very good thing in that it enables you to reduce the amount of data retrieved from the database (good) and sent over the wire (great!).


Contrived example: suppose you have two users simultaneously using a sales application, adding line items for the same large order. It would be nice if each user could see the changes the other had made without needing to reload the order. In order to accomplish the goal of having up to date data without interrupting the user experience, the client end of the sales system should occasionally request updates. If the max rowversion in the client for the selected order is less than the server's max rowversion for the selected order, you know that the server has data that hasn't made it to the client yet. The best part is you also know which records are new or modified! You only need to send the records with updates to the client, which leads to a much nicer experience for everyone.


That's all fine for updates and inserts, but what about deletes? Suppose User A deletes line 17 that User B had originally entered. If you delete a row, you also delete its rowversion entry, so User B will have to reload the order to see that change. That is not optimal. You can avoid situations like this with the addition of another column in your table, which you might name "IsActive". If you had that column, you could set "IsActive" to false which would update the rowversion and User B could see that the row was deleted the next time his/her client got new data for the order.

Friday, December 23, 2011

Editing XML


If you need to edit an XML document, there is an easier way than trying to manually edit the string.
          
XmlDocument xpathDocument = new XmlDocument();
byte[] byteArray = Encoding.ASCII.GetBytes(xmlData); 
//xmlData is a valid XML object stored as a string.
xpathDocument.Load(new MemoryStream( byteArray ));
XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();
  
//Update the xmlData's OpenText node (child of root).
xpathNavigator.SelectSingleNode(".//OpenText").SetValue("New Open Text Value");

Here is the sample XML schema:
<BidInfo>
<OpenText>Some value</OpenText>
</BidInfo>

Note that if you try to edit an object of type XPathDocument it won't work out for you, although the error messages may not immediately make it clear why. The XPathDocument class "Provides a fast, read-only, in-memory representation of an XML document by using the XPath data model. Pasted from <http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathdocument.aspx

Thursday, December 22, 2011

.NET Development Tips & Tricks


There are a multitude of tips and tricks .NET developers should know. This post covers a small subset of available tools that give you great bang for your buck. 

Here are some of my favorite tools:

Nuget: Allows you to add references to and streamline maintenance of many open source projects (including log4net, Castle, Microsoft Entity Framework, OpenXML, Spring.net, etc). You can also host your own Nuget gallery.

Reflector: "Browse, analyze, decompile and debug .NET code" - No longer free, but I'm sure it's still at least as awesome as it was. This is particularly helpful in illustrating why you should obfuscate your intellectual property.

Code Translator: If you've got a snippet of VB from a web site and you'd like it translated to C# or vice versa, this is an easy to use tool that will do the trick most of the time.

Visual Studio Extensions:
Power Commands: Collapse Projects, Open Command Prompt, Undo Close, Copy References, Paste References, Extract Constant

Productivity Power Tools:  Pinned tabs , Color tabs according to their project or according to regular expressions

Slow Cheetah: "This package allows you to automatically transform your app.config (or any file) when you press F5 in Visual Studio. You can have different transformations based on the build configuration. This will enable you to easily have different app settings, connection strings, etc for Debug versus Release. If you want to transform other files you can do that too." - It's really well done.

Hints for team development:

  1. Whenever possible, start with a Virtual Machine that has your database and other configuration chores already done. While you may pay a slight performance price for running your development environment in a VM, the time you are potentially saving in configuration nightmares is well worth it. The cost of configuration troubleshooting is almost certainly higher your team is remote.
  2. Comment your checkins! While comments on checkins should not be excessively verbose, if someone has just gotten latest and the project no longer builds, some hints about what changed will be appreciated.
  1. Check in everything when possible. If you have pending changes for other projects that you are not going to be working on in the same day, shelve them! Keep life simple, why waste time thinking about what things you can check in and what things you can't?

    Also, if you can't check something in due to configuration differences between your environment and other devs on your team, resolve the differences! It's worth it. A tool that may be very helpful is SQL Server's aliasing functionality.
  2. Be available. During normal work hours, you should be on IM or group chat as much as possible.
  1. For files that don't  handle merge conflicts well, ie edmx files, communicate when you would like to make changes and make sure that you're the only one making changes. This can save significant rework. 

Wednesday, December 21, 2011

Renaming a SQL Server Instance (Don't)


I have not come across a situation where renaming a SQL Server instance was necessary. For most development time SQL Server instance issues, creating a SQL Alias is probably the better choice.

The reason I have come across to use SQL Server Aliases is that some developers on a team have different SQL instance names. This makes maintaining configuration files tedious, and wastes time that could be used toward completing the project. This (and many other configuration issues) can be avoided if the team starts development from a common Virtual Machine.

There is an excellent writeup available here: http://geekswithblogs.net/twickers/archive/2009/12/08/136830.aspx. If you just want to know how to create your SQL Server alias, you can skim all the way down to the "
Client configuration - how to create a SQL Server Alias (easy, official way)" heading.

If you really need to rename a SQL Server instance, the following page may be helpful: http://www.modhul.com/2008/01/15/renaming-a-sql-server-instance/#ixzz1geMRljlO

Tuesday, December 20, 2011

Creating Virtual Directories Programmatically using C#


If you need to create a virtual directory in IIS, it is very easy to do through managed code. Here is an example of a method that creates a virtual directory in IIS.    

   private static void EnsureVirtualDirectoryExists(FileInfo newFile)
        {
            ServerManager iisManager = new ServerManager();
            var virtualDirectories = iisManager.Sites["Default Web Site"].Applications["/BIDSService"].VirtualDirectories;
            if (!virtualDirectories.Any(vd => vd.Path == "/Previews"))
            {
                if (virtualDirectories.AllowsAdd)
                {
                    virtualDirectories.Add("/Previews", Path.GetDirectoryName(newFile.FullName));
                    iisManager.CommitChanges();
                }
            }
        }

Monday, December 19, 2011

Code First Entity Framework & Stored Procedures


Code First for EF and Stored Procedures don’t work well together. After some searching and experimenting, the best solution I have come up with is the following:
  1. Create your sproc(s) in SQL Server Manager.
  1. Select your stored procedure(s) in the Object Explorer tab, Select “Script Stored Procedure as” -> “DROP and CREATE To” -> and save the resulting text in a file in your data model project. In my example, the file name is
CreateSprocs.sql.

  1. [Optional]: Add a Post-build event command line: sqlcmd -i CreateSprocs.sql.
  1. [Optional]: Change the CreateSprocs.sql file’s Properties for the “Copy to Output Directory” attribute to “Copy always”.

To test that it is working properly:
  1. rename the stored procedures that the script will create.
  1. if you followed the optional steps build your data model project . If you did not follow the optional steps, you will have to run the scripts in your CreateSprocs.sql file.
The stored procedures should be recreated with the appropriate names.

Note:
  1. Steps 3 & 4 are only necessary if you want to automatically update all sprocs on developers' machines each time the project is built. This may cause loss of work if several developers are working in stored procedures at once.
  1. If you do not follow the optional steps, each developer will have to manually run the CreateSprocs.sql file each time it is updated.