NHibernate на столе с двумя «первичными» ключами - PullRequest
1 голос
/ 01 июля 2011

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

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

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

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

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

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

1 Ответ

1 голос
/ 01 июля 2011

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

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 карт классов позволяет объединять столбцы, которые не являются первичными ключами для этих типов унаследованных баз данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...