C# 使用Fluent NHibernate一对一关系的正确设计是什么?

C# 使用Fluent NHibernate一对一关系的正确设计是什么?,c#,sql,nhibernate,fluent-nhibernate,C#,Sql,Nhibernate,Fluent Nhibernate,我有一张食谱表。每个配方在RecipeMetadata表中都有一行且只有一行,该表包含关于配方的各种数据,出于各种原因,我不想将这些数据存储在Recipes表中。因此,配方和RecipeMetadata具有一对一的映射。我的食谱表如下: public partial class RecipesMap : ClassMap<Recipes> { public RecipesMap() { Id(x => x.RecipeId); // Map

我有一张食谱表。每个配方在RecipeMetadata表中都有一行且只有一行,该表包含关于配方的各种数据,出于各种原因,我不想将这些数据存储在Recipes表中。因此,配方和RecipeMetadata具有一对一的映射。我的食谱表如下:

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中查找一行,其中Recipes.RecipeId=RecipeMetadata.RecipeMetadata ID。换句话说,它使用两个表上的主键进行连接

在我的表模式中,RecipeMetataId是该表唯一的键,与RecipeId无关。RecipeMetadata还有一个列,也称为RecipeId,它对“Recipes”具有外键约束。连接应起以下作用:

Recipes.RecipeId = RecipeMetadata.RecipeId
我的问题是:

我希望RecipeMetadata有自己的唯一ID,并使用单独的列将其链接到菜谱,这是错误的吗?显然,我在RecipeMetadata.RecipeId上有一个FK约束和一个唯一的索引,所以没有性能影响。是的,磁盘上有一些额外的字节,用于在此表上存储可能不必要的ID

我从未见过主键在另一个表上也有外键约束的表。这合法吗?这似乎是nHibernate默认的行为方式。我是否应该让步,让它顺其自然

如果我不想更改数据库,但如果给出合理的理由,我可以说服我这样做,那么我如何使用此模型创建所需的一对一映射


NHibernate对一对一关系有严格的定义。严格但公平。在NHibernate中,一对一关系意味着表a中的a行在表B中始终有一个匹配行

不管是对是错,NHibernate的一对一映射都不起作用。请注意,您提出的模型与一对多关系的建模方式相同。 这是合法的,并加强了一对一的关系。 由于您希望配方始终具有关联的元数据行,因此我将使用NHibernate的一对一映射对其进行建模。或者,可以将其映射为一对多,但只能将一个实例作为属性公开。
另请参见:。

那么,您是说NHibernate将一对一关系定义为共享主键的两个表?是的,没错,我应该这样说。我应该提到另一种选择,从配方方面将它映射到一个引用。这应该行得通,因为您不太可能从元数据导航或查询到配方。谢谢!这是有道理的。我更喜欢按照NHibernate建议的方式做事,因为这样做会减少今后的问题。更改架构有点麻烦,我有一些视图需要修改,但现在一切都很好。小提示:NHibernate有一对一的副作用:任何receipe的选择都会连接两个表中的数据。总是这就是NHibernate的工作原理。一对多在这里很难应用,但最终会更加灵活。一个简化的操作方法。总之,很好的Q和A@RadimKöhler-谢谢。如果性能变得至关重要,我可能会选择一对多。。我会在代码中记下这一点。
Recipes.RecipeId = RecipeMetadata.RecipeId