2011-03-31 15 views
7

Tuve una pregunta similar a Fluent NHibernate: How to create one-to-many bidirectional mapping? pero me interesaba la situación cuando tenía un mapeo de uno a uno. Por ejemploFluidez NHibernate: ¿Cómo crear mapeo bidireccional uno a uno?

Umbrealla 
    ID 
    Owner 

UmbreallaOwner 
    ID 
    Umbrella 

Como sabemos, cada sombrilla solo puede ser propiedad de una persona y nadie posee más de una sombrilla. En un mapa fluidez Me gustaría tener algo como

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

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

Al crear las tablas de fluidez creará un campo en el paraguas referncing el ID de umbrellaOwner y un campo de referencia umbrellaOwner paraguas. ¿Hay alguna manera de cambiar el mapeo de modo que solo se cree una clave foránea pero las propiedades Umbrella y Owner estarán disponibles? Los ejemplos que he visto implican el establecimiento de las relaciones en ambas direcciones por lo que añadir un nuevo paraguas parece

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

que parece lógico, pero un poco engorroso.

Respuesta

9

Bueno, una referencia es una referencia; un objeto tiene una referencia al otro. Lo contrario no es necesariamente cierto.

En su caso, PODRÍA salirse con la suya con una relación HasOne. Sin embargo, HasOne es normalmente para datos desnormalizados. Supongamos que desea obtener más información sobre el propietario, pero no puede cambiar el esquema del propietario porque el otro código depende de él. Debería crear un objeto AdditionalOwnerInfo y crear una tabla en el esquema en la que el campo OwnerID de la tabla fuera una clave externa para Owner, y también la clave principal de la tabla.

Ayende recomienda una relación de Referencias() de dos lados en el 99.9% de casos uno a uno, donde el segundo objeto está conceptualmente separado del primero, pero hay un tipo implícito "Solo yo tengo exactamente una cosa" de relación. Puede aplicar la naturaleza "uno y solo" de la referencia utilizando un modificador Unique().Not.Nullable() establecido en la asignación de Referencias.

Para agilizar la configuración referencial, considere definir un objeto (UmbrellaOwner) como el "padre" y el otro (Umbrella) como el "niño", y en el establecedor de propiedades del padre, configure el padre del hijo con la referencia actual:

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

Ahora, cuando se asigna el niño al padre, la referencia hacia atrás se fija hasta automágicamente:

var owner = new UmbrellaOwner{Umbrella = new Umbrella()}; 
Assert.AreEqual(owner, owner.Umbrella.Owner); //true; 
Cuestiones relacionadas