Fluent NHibernate: How to create a one-to-one bidirectional mapping?

I had a similar Fluent NHibernate question : how to create a one-to-many bidirectional mapping? but I was interested in the situation, for one. For example,

Umbrealla ID Owner UmbreallaOwner ID Umbrella 

As we know, each umbrella can belong to only one person, and no one owns more than one umbrella. On a paid card, I would have something like

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

When creating tables, freely create a field in the umbrella that refers to the identifier of the operator umbrella and a field in the umbrella. A call that refers to an umbrella. Is there a way to change the mapping so that only one foreign key is created, but the Umbrella and Owner properties exist? The examples I saw relate to establishing relationships in both directions, so adding a new Umbrella looks like

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

which seems logical, but a little cumbersome.

+7
source share
1 answer

Well, a link is a link; one object has a link to another. The converse is not necessarily true.

In your case, you can get away with HasOne relationships. However, HasOne is commonly used for denormalized data. Say that you need additional information about the owner, but you cannot change the owner’s scheme, because another code depends on it. You must create an AdditionalOwnerInfo object and create a table in the schema in which the OwnerID field of the table was the foreign key for the owner, as well as the primary key of the table.

Ayende recommends a two-way reference () in 99.9% of the one-to-one cases, where the second object is conceptually separate from the first, but there is an implicit type of "I own only one thing" relationship. You can enforce the "one and only one" character of a link using the Unique().Not.Nullable() set in the link mapping.

To streamline the reference setting, consider defining one object (UmbrellaOwner) as a "parent" and another (Umbrella) as a "child", and in the parent property installer set the parent parent element to the current link:

 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; } } } 

Now, when you assign a child to a parent, the backreference function is automatically configured:

 var owner = new UmbrellaOwner{Umbrella = new Umbrella()}; Assert.AreEqual(owner, owner.Umbrella.Owner); //true; 
+9
source

All Articles