NHibernate映射表是主键也是外键

时间:2010-11-30 20:44:28

标签: sql sql-server nhibernate hibernate

我有两张表如下:

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。

有什么建议吗?

1 个答案:

答案 0 :(得分: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

您还可以保留原始架构,并将关系映射为从User到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 } 
    }
}