Setting MaxValue for Migrations

12 03 2013

I’ve just been using the MigratorDotNet framework for the first time. I was creating a migration that would create a new table with various new fields. One of the fields I wanted to create was to store files so therefore I wanted a varbinary(max) field. If you leave the size undeclared, it will create a varbinary(8000). The way I got around this was to create my column as follows:

Column file = new Column("BinaryFile", System.Data.DbType.Binary, int.MaxValue, ColumnProperty.NotNull);

Using the int.MaxValue gives the same result as varbinary(max). However, this doesn’t create a varbinary(max) field (at least not in SQL Server 2008 R2 which is what I am using). It creates an image field instead. This isn’t necessarily a problem, it still gives me the space I require. Importantly though, Microsoft are now advising you do not use this type in new development as it will be removed in a future version of SQL Server (see MSDN article here). We’ve weighed this up and have decided that this is not a problem for us at this time because we are developing improvements to a current system with no plans for any SQL upgrade in the future. There are also uses of the image type in other parts of the database. We have instead logged it in our technical backlog to go through and change all uses of this type at a later date. Personally, in a new project, I would not use it, just in case!

I did some searching in the hope I would find a more elegant solution (something akin to the EF Code First data annotations would have been nice) but I didn’t find anything. If anybody comes across this post, and you’ve found a nicer way to do this, please comment on here to let me know!

Running command line commands from C#

2 04 2009

I needed to make a Windows Service that watched folders defined in an XML file for any new events. Upon a new file being created, I needed to call an executable file and pass some arguments via the command line for each file in the folder, and the executable needed to be called sequentially.

I had various issues with this. Upon my research I discovered there are multiple ways to do this. Not only multiple ways to write to the command line, but also I could have done it via a batch file. My solution required writing directly to the command line however, and below is the code I used in my final realease.

Process runMap = new Process();
runMap.StartInfo.WorkingDirectory = @"C:/Project/maps";
runMap.StartInfo.FileName = @"C:/Project/executables/dstx.exe";
runMap.StartInfo.Arguments = TRIGGER_MAP + " -b";

In my case, the WaitForExit() command is important because I need each file to run one at a time. The Close() is important, otherwise the Process will stay open and your processes in your Task Manager will fill with whatever executable you are calling.

As I said, there are so many ways of doing this. This is just the one that worked for me. If this one doesn’t work for you, you have plenty of other options! If anyone reading this is having a problem getting this code to run in a Windows Service like I was, and it doesn’t seem to be working, make sure your service is able to interact with the desktop! I had the same problem 🙂

Constraint check using regular expressions

19 02 2009

I needed to check the values of a text box (with folder paths in them) to ensure they matched a constraint on the table in the database. There are a few ways you could do this, I initially thought I could check the relevant characters in the string using String.Substring() to see if they met the constraints, in this case, the first must not be a backslash and the last must be a backslash.

However I then thought it would be better to do a much more robust way, not just checking for backslashes, but also valid characters in file paths. This is how I came up with the idea to use a regular expressions. They are very useful bits of code, and definitely worth reading up on! The code I used was:

if (!Regex.IsMatch(txtMapLocation.Text, @"^[0-9a-zA-Z].*\\$"))
MessageBox.Show("Your map location must end with a backslash and there must be no backslash at the start.");

The regular expression broken down means…

^ (right at the very beginning) [0-9a-zA-Z] (there must be a number or letter, upper or lower case allowed) .*(as many letters or numbers as you wish)\\(then there must be a backslash)$(right at the end). The backslash is double slashed as backslashes are an escape character in regular expressions.