SubSonic 3.0

Google AdSense

I’ve used SubSonic 2.x for a while and I’ve blogged about how useful it was as a tool to aid my development projects. A few weeks ago, SubSonic 3.0 was released and I hadn’t spent much time reviewing the updates and changes to version 3.0 until this week.

At the present, I have several large projects using SubSonic 2.x and I have a new smaller project starting this week. So I decided to download and install SubSonic 3.0 and use the small project to get familiar with the updates prior to updating my other web sites from 2.x to 3.0.

Continue reading

How to serialize SubSonic objects with nullable properties

Google AdSense

Recently, I ran into the following error when trying to serialize some SubSonic generated classes.

Cannot serialize member ‘XXX’ of type System.Nullable`1[XXX]. XmlAttribute/XmlText cannot be used to encode complex types.

The SubSonic autogenerated classes cannot serialize nullable types such as DateTime? and GUID?. This is really a .NET serialization problem and not directly related to SubSonic, since the SubSonic library just uses the native .NET code for serialization.

Continue reading

How to use custom audit fields with SubSonic

SubSonic uses a few audit fields by default – you don’t need to write any code. However, the field names that are used are coded into the source code. You can modify the source code and generate a new assembly, but if you’re like me and would rather not edit the source code (so you don’t need to update the code at every release), then you’ll be looking for an alternative approach.

Continue reading

How to perform an aggregate query using SubSonic 2.1’s SqlQuery

Just recently, I upgraded from SubSonic 2.0 to SubSonic 2.1 RC1. One of the new features is the addition of the SqlQuery class and it’s ability to perform aggregate queries (along with many other features).

If you’re not familiar with SubSonic, then it is a tool that builds your DAL (Data Abstraction Layer). Each of your database, tables, and rows become classes that you can insert, update, delete, and select from.

By using an ORM instead of embedding SQL statements in your applications, it makes your code easier to test and catch mistakes (such as typos in field or table names). There’s pros and cons to ORM versus SQL statements, but this entry won’t touch on those issues.

This is an example of how to perform a query to get a count of unique records while grouping by a column.

Continue reading

Debugging assembly loading within a unit test project

I reorganized one of my projects and discovered that my MbUnit tests no longer worked. The error stated that one of the assemblies could not be loaded, but it worked fine before I removed and added the project to another solution. The assembly in question was the SubSonic assembly.

This took me a little while to work through and I wasn’t able to find any helpful blogs or documentation to help. So I figured that I’ll contribute to the blogosphere and maybe someone else might find this useful.

I thought through the problem and finally figured it out. I had forgotten about how MbUnit executes. Even though, MbUnit’s output is sent to the Visual Studio’s output window, the tool runs in a separate process – remembering that I was able to debug and figure out how to solve my problem.

The root cause was that the assembly wasn’t in the working directory for the test assembly so it couldn’t be loaded by MbUnit. The SubSonic assembly was not in the GAC, the SubSonic directory wasn’t in my %PATH%, and the assembly’s “Copy Local”property was set to false.

By changing the “Copy Local” property, the test project automatically copied the SubSonic assembly to the bin directory and MbUnit was then able to load the assembly without any errors. Alternatively, you could add SubSonic to your GAC (Global Assembly Cache) or add the SubSonic directory (the directory with the .dll file) your environment path. Here’s a little more information and the steps I used to resolve the problem.

Software

  • Visual Studio Professional 2005
  • SubSonic 2.0.3
  • MbUnit 1.0.2700 Add-in
  • TestDriven 2.8 Add-in

Symptoms

TestCase failed: An error occurred creating the configuration section handler for SubSonicService: Could not load file or assembly ‘SubSonic’ or one of its dependencies. The system cannot find the file specified.

System.Configuration.ConfigurationErrorsException

Message: An error occurred creating the configuration section handler for SubSonicService: Could not load file or assembly ‘SubSonic’ or one of its dependencies. The system cannot find the file specified.

Source: System.Configuration

StackTrace:
    at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
    at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission)
    at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
    at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
    at System.Configuration.ConfigurationManager.GetSection(String sectionName)
    at SubSonic.DataService.LoadProviders()
    at SubSonic.DataService.GetInstance(String providerName)

Inner Exception:
    System.IO.FileNotFoundException
    Message: Could not load file or assembly ‘SubSonic’ or one of its dependencies. The system cannot find the file specified.

Source: System.Configuration

StackTrace:
    at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
    at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.Init(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
    at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.InitWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
    at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory..ctor(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
    at System.Configuration.RuntimeConfigurationRecord.CreateSectionFactory(FactoryRecord factoryRecord)
    at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)

Solution

  1. Expand “References” of the Test project
  2. Select “Subsonic” library
  3. Set “Copy Local” to true
  4. Rebuild the test project