2011-07-01 4 views
1

J'apprends NHibernate pour le superposer sur une base de données héritée plutôt particulière. D'autres applications utilisent la même base de données en direct, donc je ne peux pas apporter de modifications qui les affecteront.NHibernate sur une table avec deux clés "primaires"

J'ai rencontré un problème car une table, qui représente les périphériques matériels, a deux colonnes utilisées comme clés primaires de facto. L'un est la clé primaire réelle, un identifiant de ligne généré automatiquement. L'autre est un numéro de série matériel unique et non nul.

De nombreuses autres tables de la base de données ont une relation de clé étrangère avec cette table. Cependant, certains d'entre eux utilisent la clé primaire réelle - l'identifiant de ligne entier - comme une clé étrangère, et certains utilisent à la place l'identifiant matériel du périphérique.

Notez qu'en pratique, un ID de matériel et un ID de ligne, une fois couplés, resteront couplés. Est-ce que je serai capable de créer des mappages pour gérer cela avec NHibernate, ou devrais-je créer des vues pour me donner un schéma plus standardisé, et utiliser des déclencheurs INSTEAD OF pour les rendre modifiables?

La base de données utilisée est MSSQL 2000, au cas où cela ferait une différence.

Répondre

1

Dans votre situation je ferais ce qui suit:

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 
} 

Plan de votre classe HardwareDevice en utilisant l'identifiant AutoGénéré comme la clé primaire. Mes exemples utilisent FluentNhibernate pour les cartes de classe.

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

Maintenant, pour cartographier les deux autres 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 
    } 
} 

La fonction de propriété Ref des cartes de classe vous permet de joindre des colonnes qui ne sont pas la clé primaire pour ces types de base de données existante fins.

Questions connexes