2010-11-30 88 views
0

我有2個表如下:NHibernate的映射表格是主要密鑰也外鍵

create table Users 
(
UserId int primary key identity not null 
) 

create table UserExternalKeys 
(
UserIdRef int primary key not null, 
ExternalKey varchar(50) unique not null 
) 

alter table UserExternalKeys 
add constraint fk_UsersExternalKeys_Users 
foreign key (UserIdRef) 
references Users (UserId) 

每個用戶可具有0或1外部鍵。事情是這樣設置的,因爲向SQL Server添加一個可爲空的唯一列不允許超過1個空值。

基於Ayende's post,似乎可以使用<one-to-one>映射來處理。但是,這需要UserExternalKeys表具有自己的主鍵。

新的模式將是這個樣子:

create table Users 
(
    UserId int primary key identity not null, 
    ExternalKeyRef int null 
) 

create table UserExternalKeys 
(
    UserExternalKeyId int primary key identity not null, 
    ExternalKey varchar(50) unique not null 
) 

alter table Users 
add constraint fk_Users_UsersExternalKeys 
foreign key (ExternalKeyRef) 
references UserExternalKeys (UserExternalKeyId) 

,我認爲這會工作,但感覺就像我只會添加UserExternalKeyId列安撫NHibernate的。

有什麼建議嗎?

+0

添加列只是爲了安撫NHibernate就像一個成年儀式。 – marr75 2010-11-30 21:15:53

回答

2

如果用戶可以具有0或1爲什麼不設計的表作爲外部鍵:

create table Users 
(
    UserId int primary key identity not null 
    ExternalKey varchar(50) null 
) 

,並使用針對此問題已知的解決方法之一。如果您使用SQL Server 2008,則可以使用filtered index。如果您使用的是早期版本,則可以使用觸發器,索引視圖(2005)或nullbuster workaround

您也可以保留您的原始架構,並將關係映射爲用戶與UserExternalKeys之間的一對多關係。將該集合映射爲私有成員,並通過屬性公開對其的訪問:

private IList<UserExternalKeys> _externalKeys; 

public string ExternalKeys 
{ 
    get 
    { 
     if (_externalKeys.Count() == 1) 
     { 
      return _externalKeys.ElementAt(0).ExternalKey; 
     } 
     else 
     { 
      // return null or empty string if count = 0, throw exception if > 1 
     } 
    } 
    set 
    { 
     if (_externalKeys.Count() == 0) { // add key and set value } 
     else { // set value if count = 1, throw exception if > 1 } 
    } 
} 
+0

我以前曾經遇到過這個問題,但從未聽說過這個零零碎碎的解決方法,也沒有想過索引視圖。 (我用觸發器來做到這一點有點臭)。過濾後的指數將是最好的,但我暫時停留在2005年。 由於我不想大驚小怪的遺留代碼,我最終使用第二模式並創建了從用戶到密鑰的多對一關係。但事實告訴我,我更喜歡你的一些建議:) – dana 2010-12-01 23:47:07

相關問題