开发者

NHibernate on a table with two "primary" keys

I'm learning NHibernate in order to layer it over a rather peculiar legacy database. Other applications use the same live database, so I can't make changes that will affect them.

I've run into a problem because one table, which represents hardware devices, has two columns that are used as de facto primary keys. One is the real primary key, an auto-generated row id. The other is a unique and non-null hardware serial number.

Many other tables in the database have a foreign-key relationship with this table. However, some of them use the real primary key - the integer row id - as a foreign key, and some use the hardware id of the device instead.

Note that in practice a hardware ID and row ID, once paired, will remain paired.

Will I be able to create mappings to deal with this in NHibernate, or will I need to create some views to give me a more standardized schema, and use INSTEAD OF trig开发者_Python百科gers to make them updatable?

The DB in use is MSSQL 2000, in case this makes a difference.


In your situation I would do the following:

public class HardwareDevice{
    public virtual int Id {get; set;}
    public virtual string SerialNumber {get; set;}
    //Other stuff
}

public class DomainThingA {
    public virtual int Id {get; set;}
    public virtual HardwareDevice Device {get; set;}
    //Other stuff
}

public class DomainThingB {
    public virtual int Id {get; set;}
    public virtual HardwareDevice Device {get; set;}
    //Other stuff
}

Map out your HardwareDevice class using the AutoGenerated Id as the primary key. My examples use FluentNhibernate for the class maps.

public class HardwareDeviceMap : ClassMap<HardwareDevice> {
    public HardwareDeviceMap(){
        Id(x=>x.Id).GeneratedBy.Native().Column("Id"); //Uses auto number
        Map(x=>x.SerialNumber).Column("SerialNumber");
        //Other mappings
    }
}

Now for mapping out the other two classes:

public class DomainThingAMap : ClassMap<DomainThingA> {
    public DomainThingAMap(){
        Id(x=>x.Id).GeneratedBy.Native(); //Uses auto number
        References(x=>x.Device)
          .Column("DeviceId"); //Joins on Id in HardwareDevice Table by default
        //Other mappings
    }
}

public class DomainThingBMap : ClassMap<DomainThingB> {
    public DomainThingBMap(){
        Id(x=>x.Id).GeneratedBy.Native(); //Uses auto number
        References(x=>x.Device)
           .Column("SerialNumber") //Column in DomainThingB Table
           .PropertyRef("SerialNumber"); //Joins using SerialNumber column (hardware device table)
        //Other mappings
    }
}

The Property-Ref feature of the class maps allows you to join on columns which are not the primary key for these types of legacy database purposes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜