NHibernate на таблице с двумя первичными ключами

Я изучаю NHibernate, чтобы наложить его на довольно своеобразную устаревшую базу данных. Другие приложения используют ту же живую базу данных, поэтому я не могу вносить изменения, которые повлияют на них.

Я столкнулся с проблемой, потому что одна таблица, представляющая аппаратные устройства, имеет два столбца, которые фактически используются в качестве первичных ключей. Один из них - настоящий первичный ключ, автоматически сгенерированный идентификатор строки. Другой - уникальный и непустой серийный номер оборудования.

Многие другие таблицы в базе данных связаны с этой таблицей по внешнему ключу. Однако некоторые из них используют реальный первичный ключ - целочисленный идентификатор строки - в качестве внешнего ключа, а некоторые вместо него используют аппаратный идентификатор устройства.

Обратите внимание, что на практике идентификатор оборудования и идентификатор строки, будучи спаренными, остаются парными.

Смогу ли я создать сопоставления для решения этой проблемы в NHibernate, или мне нужно будет создать несколько представлений, чтобы дать мне более стандартизованную схему, и использовать триггеры INSTEAD OF, чтобы сделать их обновляемыми?

Используемая БД - MSSQL 2000, на случай, если это имеет значение.


person JohnCC    schedule 01.07.2011    source источник


Ответы (1)


В вашей ситуации я бы сделал следующее:

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
}

Составьте карту своего класса HardwareDevice, используя AutoGenerated Id в качестве первичного ключа. В моих примерах для карт классов используется FluentNhibernate.

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
    }
}

Теперь для отображения двух других классов:

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
    }
}

Функция Property-Ref карт классов позволяет объединять столбцы, которые не являются первичным ключом для этих типов целей устаревшей базы данных.

person Mark Perry    schedule 01.07.2011