流畅的NHibernate:如何创建一对一的双向映射?

sti*_*mms 7 nhibernate fluent-nhibernate

我对Fluent NHibernate提出了类似的问题 :如何创建一对多双向映射?但是当我有一对一的映射时,我对这种情况很感兴趣.例如

Umbrealla
  ID
  Owner

UmbreallaOwner
  ID
  Umbrella
Run Code Online (Sandbox Code Playgroud)

据我们所知,每把伞只能由一个人拥有,没有人拥有一把伞.在一张流利的地图中我会有类似的东西

UmbrellaMap()
{
   Id(x=>x.ID);
   References<UmbrellaOwner>(x=>x.Owner);
}

UmbrellaOwnerMap()
{ 
   Id(x=>x.ID);
   References<Umbrella>(x=>x.Umbrella);
}
Run Code Online (Sandbox Code Playgroud)

当创建表格时,流畅的将在伞中创建一个字段,引用umbrellaOwner的ID和umbrellaOwner引用伞中的字段.是否有任何方法可以更改映射,以便只创建一个外键但是Umbrella属性和Owner属性都存在?我看到的例子涉及在两个方向上设置关系,所以添加一个新的Umbrella看起来像

AddUmbrealla(UmbrellaOwner owner)
{
   var brolly = new Umbrella();
   brolly.Owner = owner;
   owner.Umbrella = brolly;
   session.Save(owner); //assume cascade
 }
Run Code Online (Sandbox Code Playgroud)

这似乎合乎逻辑但有点麻烦.

Kei*_*thS 9

那么,参考是一个参考; 一个对象引用另一个对象.反过来不一定如此.

在你的情况下,你可能会逃脱HasOne关系.但是,HasOne通常用于非规范化数据.假设您想了解有关所有者的更多信息,但您无法更改所有者的架构,因为其他代码依赖于它.您将创建一个AdditionalOwnerInfo对象,并在架构中创建一个表,其中表的OwnerID字段是Owner的外键,也是表的主键.

Ayende建议在99.9%的一对一案例中使用双边References()关系,其中第二个对象在概念上与第一个对象分开,但有一个隐含的"我独自拥有一件事"类型的关系.您可以使用Unique().Not.Nullable()"引用"映射上设置的修改器强制执行引用的"仅一个"性质.

要简化参照设置,请考虑将一个对象(UmbrellaOwner)定义为"父",将另一个(Umbrella)定义为"子",并在父项的属性设置器中将子项的父项设置为当前引用:

public class Umbrella
{
  public virtual string ID { get; set; }
  public virtual Owner Owner { get; set; }
}

public class UmbrellaOwner
{
  public virtual string ID { get; set; }
  private Umbrella umbrella;
  public virtual Umbrella Umbrella
  {
    get{
      return umbrella;
    }
    set{
      umbrella = value;
      if(umbrella != null) umbrella.Owner = this;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,当您将子项分配给父项时,将自动设置反向引用:

var owner = new UmbrellaOwner{Umbrella = new Umbrella()};
Assert.AreEqual(owner, owner.Umbrella.Owner); //true;
Run Code Online (Sandbox Code Playgroud)