我有一张食谱表。每个Recipe在RecipeMetadata表中只有一行,其中包含有关该Recipe的各种数据,由于各种原因,我不想将这些数据存储在Recipes
表中。因此,Recipes
和RecipeMetadata
具有一对一的映射。我的Recipes
表如下:
public partial class RecipesMap : ClassMap<Recipes>
{
public RecipesMap()
{
Id(x => x.RecipeId);
// Map() various columns here
HasMany(x => x.Ingredients).KeyColumn("RecipeId");
HasOne(x => x.Metadata);
}
}
这是我的RecipeMetadata
表格:
public partial class RecipeMetadataMap : ClassMap<RecipeMetadata>
{
public RecipeMetadataMap()
{
Id(x => x.RecipeMetadataId);
// Map() various columns here
References<Recipes>(x => x.Recipe).Column("RecipeId").Not.Nullable();
}
}
但是,当我加载Recipe
并访问Metadata
属性时,它会尝试在RecipeMetadata
中查找Recipes.RecipeId = RecipeMetadata.RecipeMetadataId
所在的行。换句话说,它使用两个表上的主键进行联接。
在我的表模式中,RecipeMetadataId
是该表唯一的键,与RecipeId
无关。RecipeMetadata
有另一列,也称为RecipeId
,它对`Recipes有外键约束。JOIN的工作方式应该是:
Recipes.RecipeId = RecipeMetadata.RecipeId
我的问题:
我希望
RecipeMetadata
有自己的唯一ID,并使用单独的列将其链接到Recipes
,这错了吗?显然,我在RecipeMetadata.RecipeId
上有一个FK约束和一个唯一索引,所以没有性能影响。是的,磁盘上有一些额外的字节,用于在这个表上存储一个可以说是不必要的ID。我从未见过一个表的主键在另一个表上也有外键约束。这种做法合法吗?默认情况下,这似乎是nHibernate更喜欢的行为方式。我应该让步让它顺其自然吗?
如果我不想更改数据库(尽管如果有正当理由,我可以被说服这样做),我如何用这个模型创建所需的一对一映射?
NHibernate对一对一关系有严格的定义。严格但公平。在NHibernate中,一对一关系意味着表a中的一行在表B中总是有一个匹配的行。
- 无论是对是错,NHibernate的一对一映射都不起作用。请注意,您提出的模型与一对多关系的建模方式相同
- 它是合法的,并加强了一对一的关系
- 由于您希望配方始终有一个关联的元数据行,因此我将使用NHibernate的一对一映射对其进行建模。或者,您可以将其映射为一对多,但只将一个实例作为属性公开
另请参阅:Ayende关于该主题的帖子。