我有两张表如下:
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 :(得分: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 }
}
}