Monday, 14 July 2008

LinqtoDBMLRunner improvements

I've made a couple of improvements. Generally you want to make a couple of changes to an element in the xml file once you've selected it. The Apply extension method allows you to chain changes together so you don't need to keep reselecting objects e.g.

root.Table("People")
    .Apply(table => table.Member = "Persons")
    .Apply(table => table.Type
                        .Apply(type => type.Name = "Person")
    );

The next improvement is a method to automatically recognise single table inheritance from the database, if, of course, you stick to the convention.

Image you have a table defined with the following SQL. The underscores in the column names are used to indicate that the column should belong to a subclass.

CREATE TABLE [dbo].[Device](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [DeviceType] [int] NOT NULL,
    [Mouse_NumberOfButtons] [int] NULL,
    [Keyboard_NumberOfKeys] [int] NULL,
    [Keyboard_WirelessKeyboard_Frequency] [decimal](19, 5) NULL,
)

You can then add the line below to your DbmlRunner script

root.ExtrapolateSubclasses();

This will rearrange your Dbml mappings to give the correct inheritance, as in the diagram below

DbmlMappings

This lets you very quickly and easily add new subclasses without having to do any real dbml scripting. A word of warning. It generates the inheritance modifier value for the subclass based on the order the columns appear in the system. If you remove a subclass and its columns once you have data in the system, you'll probably want to manually script the inheritance modifier values yourself. I might make it run off a named enum in the future, theres an idea...

Submit this story to DotNetKicks