Monthly Archives: May 2013

EntitySpaces – Access Multiple Databases Dynamically

I’ve been using EntitySpaces ORM (http://entityspaces.net) for a number of years now in my consulting work. They recently (late 2012) shut up shop and open sourced the code. It was a bit of a shame, not to mention quite surprising, as I thought they were a great company with a great product. But I’m very grateful they open sourced the project and it’s available for download from cnet.com… the full product, with all the tools, bells and whistles! Awesome stuff.

I recently came across the problem of how to dynamically access multiple databases for an Admin app I was building. A customer has 5 different databases that the Admin user can access to create, update or delete certain records. There can be multiple users logged in at once and therefore we need each user’s current database choice to be independent of each other. But I had a problem.

Normally, you would simply store the database choice (eg: country) in the users session ready for access whenever you need to hit the database. EntitySpaces has a nice mechanism for doing this. They provide an IConnectionNameService interface:

You add the database name to your session, and then when you call the EntitySpaces code, it will invoke the GetName() method and retrieve it from the session again and dynamically set which connection string to use from your web.config file.

This will work just fine on one condition – your database access code is running in the ASP.NET session context! What if your code is running in a separate .dll that is included in the project and knows nothing about the web, or ASP.NET or HTTP etc…??

You could try some of the following options:

  1. Pass the database name around from the web context to the DAL code. This means muddying the code with extra parameters and somehow keeping track of user context and thread safety.
  2. Create some sort of alternate collection to track which user is needing to connect to each database. maybe a hashtable/dictionary for quick look up. Here you would need to link back to the lookup class from anywhere where the database was being called.
  3. Find another mechanism for storing the user context and hooking into the EntitySpaces provided IConnectionNameService interface.

Options 1 and 2 simply aren’t practical and would make the code simply too messy. Option 3 though, has potential and with a bit of lateral thinking will provide the best solution.

Given that we are running in a web context on the ASP.NET stack, we have access to the Web Security framework and if we have an authenticated user who has logged in with their email address as their username, for example, we can use the current security context on the current thread as a unique way of storing the name of the database we want to connect to.

If I’m logged into my website then security identity context is going to hold the following information (I’m using forms authentication):

You can see that the Identity holds my login username – in this case my email address. So we can use this as a system wide unique ‘key’ into some collection where we can store which database name we want.

  1. We need a data store that is going to be accessible when the web application first fires up.
  2. We need to be able to store a reference to it that will persist and still be around independent of the ASP.NET Session.
  3. It would be nice to have some thread safety mechanism to allow for synchronized access.

A very nice and handy solution that ticks these boxes is the AppStart Dictionary which is automatically available to all pages in the website. It has the added benefits of providing synchronized access with it’s Lock() and UnLock() methods. We could use the global cache, and this would work quite nicely, but it doesn’t have synchronized access, although it does provide fine grain control over the life of the objects stored in it.

In a WebPages Razor website you would setup your EntitySpaces connection in the _AppStart.cshtml page:

We pass in a reference to the AppState ready to be accessed when the DAL code comes looking for which connection string to use. Here is our implementation of the IConnectionNameService interface:

Now, all we have to do is store the database name in the AppState global dictionary when the user is about to request something from the database:

Our Identity.Name (ie.email address) should be the same here as when the IConnectionNameService interface implementation is called later in the DAL custom .dll. Using a drop down select box in the web interface, you can dynamically change the database to connect to with each request.

As long as you store the country in the AppState dictionary, the EntitySpaces framework will pick it up and dynamically set it correctly each time. Very nice!

ASP.NET Sessions

Did you know that if you don’t put anything into an ASP.NET session, it will generate a new one with EVERY page request!!???

Try it out for yourself…

  • Create a new MVC(3/4) Web App in Visual Studio.
  • Choose the Razor rendering engine
  • Add the following code to index.cshtml

Run the website and you will see that the Session ID is different every time you click back to, or refresh the index page!

At first I though this was because I wasn’t logged in. If I go to the Register.cshtml page and create a new account, and login with it, this behaviour still persists.

It’s only when you add something to the session that you see the same Session ID being reused.

Go to the About.cshtml page and add the following code:

Run the app again, and make a note of the Session ID on the index.cshtml page. Next click the About menu tab, and then go back to the Home tab. You will see that your Session has been persisted because you added today’s name into the collection.

Why does it work this way? I’m not really sure. If you have any ideas, I’d be happy to hear them.

Mac OS X, Bootcamp, Virtual Machines and SSD Performance

I have a 17″ Macbook Pro configured with a bootcamp partition. I usually do my daily development work on this when I have to go on site at a client. I work with Visual Studio 2010 building web apps and desktop tools.

As soon as I bought the laptop I replaced the stock 750GB 5400rpm drive with a 480GB OWC SATA3 SSD. I also added a data doubler kit from MacSales and replaced the DVD drive with a 250GB Corsair SATA2 SSD.

After some hair pulling and firmware upgrades to the Macbook Pro I was able to get some great benchmark speeds on the OWC SSD under Mac OS X, but under Windows the speeds were only averaging SATA 2 speeds.

These are the Mac OS X benchmarks:

17″ MacBook Pro – Running Lion OS

OWC Mercury Electra 6G 480GB – Mac OS X

The performance was as expected – Max Read Avg. 520MB/s and Max Write Avg. 469MB/s. These results are what you’d expect from a SATA 3 SSD.

Next I booted into bootcamp, running Windows 7 – 64 bit (Bootcamp v3.3) , and expected to see some similar results. But this was not to be. This is what I found instead:

OWC Mercury Electra 6G 480GB – Windows 7 Pro (Bootcamp v3.3 64 bit)

As you can see, the throughput seems to be capped around the 240MB/s – 250MB/s – for both Reads and Writes. Quickbench and ATTO Disk Benchmark show this very consistently, however there is a bit more variance with Crystal Disk Mark and AS SSD Benchmark. I put these differences down to variations in the tools and possibly other disk activity. But you get the picture. Something isn’t right.

After a lot of hunting around the various Apple and OWC/Macsales forums and blogs etc… I couldn’t find anyone who had noticed this difference in performance. Eventually after opening an email dialog with the OWC staff, they determined that the bottleneck is the Apple Bootcamp drivers. I was running 64bit windows with bootcamp v3.3, so I’m not sure if it was a 64bit issue and switching to 32 bit Windows would have produced a different result. I had 16GB RAM so didn’t want to forego the memory benefits of running a 32bit OS.

**Edit** I see now that Apple have release Bootcamp v5.0 which is 64bit only for Windows 7 & 8. These SATA driver issues might well be fixed now. I haven’t tested these combinations though.

So what to do now? I’ve got an awesome laptop with a super fast hard drive and I want to get the most out of it… in both Mac OS X as well as Windows.

The answer is Virtual Machines!! My hypothesis was that if the Mac OS X drivers were heaps faster than the bootcamp drivers, I could probably run Windows in a virtual machine, under either Parallels Desktop or VMware Fusion with a better result – despite a virtualised hard drive – than natively on the bootcamp partition. Would I be proven right!!?? Lets see!

For the purpose of these tests I used the Windows Experience Index (WEI) as the best way to compare all the different permutations of VM & bootcamp etc… 

I used Parallels Desktop version 7.0 and VMware Fusion version 5.03. In all cases each virtual machine was given 4 processors and 8GB of RAM.

First of all, lets start with Windows 7 (64 bit) running under Bootcamp v3.3:

This is effectively our baseline benchmark. A 6.9 overall, with a 7.0 on the primary hard disk. Note that memory and CPU are pretty good too.

Next step is to see what scores I can get by running a VM, that is attached to the bootcamp partition – effectively running a native disk.

Parallels with Native Bootcamp Partition – Win 7 x64

This is Parallels running the native bootcamp partition. Disk speed has already jumped to a 7.6 despite a drop to 5.9 for an overall score. Not bad. Lets see what Fusion can do:

VMware Fusion with Native Bootcamp Partition – Win 7 x64

Fusion gives us a slightly better score overall, but the hard disk rating has dropped to 7.1. Bummer! Look at those CPU and memory scores though. They are doing better than our baseline, booting natively into the bootcamp partition!!

Next I created 2 new virtual machines, one each in Parallels and Fusion, but this time running Windows 8 (64bit).

Parallels with Windows 8 x64 in VM – Virtual Disk

Wow! Look at that… an 8.4 disk score! CPU and memory are still about the same, but the overall score of 5.9 has dropped as a result of the poor graphics performance.

Fusion with Windows 8 x64 in VM – Virtual Disk

VMware Fusion was just pipped at the post on this one. Disk score of 8.3 is nearly the same, but the graphics lets it down again. However we got a bump on the memory score!

So what does all this mean?? What did I choose to go with?

Well, despite the slightly slower score, I chose VMware Fusion. Why did I do this? I have been a long time user of VMware Workstation and I absolutely love it and couldn’t live without it for my day to day development activities. The two products are compatible with each other so if I need to migrate existing virtual machines I have across to Fusion, I can do that easily. I know that Parallels has some nice import features too, and I’ve used them successfully too.

But in the end it was close enough that I don’t think it would really matter. I know this is a long post, but hopefully it’s been helpful for you if you’ve been wondering about whether it’s worthwhile running Windows VM’s under Max OS X instead of going the bootcamp route. In my opinion, it is absolutely not only a viable option, but a performant one too. I have now deleted my bootcamp partition, migrated it across to a Fusion VM for archive purposes, and I am in the process of building up Fusion VM with Windows 8 x64, Visual Studio 2012 and SQL Server 2012 to do all my .Net development. So far it’s working great.