2010-09-03 15 views
7

Tengo una tabla secundaria que contiene una identificación para el padre. Este es un mapeo uno a uno, pero a la tabla hija pueden faltar valores. Tengo problemas para mapear esto sin obtener un error ... He intentado varias cosas; mapeo de la misma columna, con propiedades distintas, etc ..Usando una referencia como id en fluentnhibernate

 
Parent table 
    int id 

Child table 
    int parentid 

Parent class 
    int id 

Child class 
    Parent parent // note I'm referencing parent, not using an int id.. 

Mapeo

Id(x => x.Parent) 
    .Column("parentid"); // fails 

Id(x => x.Parent.Id) 
    .Column("parentid"); // fails 

References(x => x.Parent) 
    .Column("parentid"); // fails - missing id 

// Adding an id field in addition to parent for 
// child class (id is then the same as parent.id) 
// fails on save 
Id(x => x.Id) 
    .Column("parentid"); 
References(x => x.Parent) 
    .Column("parentid"); 

Me gustaría que la clase hija no tener un campo de ID distinto, sino sólo una referencia a los padres, ya que puede nunca seas un niño sin un padre En la base de datos, sin embargo, quiero simplemente almacenar la identificación de los padres.

Alguna idea de cómo podría hacer esto?

Respuesta

5

las siguientes obras:

Id(x => x.Parent.Id).Column("MemberID"); 
References(x => x.Parent).Column("MemberID").ReadOnly(); 

El ReadOnly de la referencia es importante no obtener una excepción

EDIT: ¿No era tan simple ...

Mi clase hija todavía tenía la propiedad Id que se llama. Parece que la referencia Id para Parent.Id confunde nhibernate, y en su lugar intenta llamar a child.Id. Agregué lo siguiente a mi hijo, y ahora parece funcionar ... Sin embargo, un hack bastante feo.

public virtual int Id { 
    get { return Parent.Id; } 
    set { Debug.Assert(value == Parent.Id); } 
} 
+0

1 trabajado para mí aquí, pero hay una manera más elegante de hacerlo? –

0

API de FluentNHibernate ha cambiado con los años así que no estoy seguro de si esta sintaxis estaba disponible cuando esta pregunta se formuló originalmente, pero ahora se puede utilizar una referencia como un identificador si asigna como una identificación con compuesto. No llamaría a esto un truco, pero es un poco extraño que tenga que mapear la referencia a la entidad padre como parte de una identificación compuesta. Aquí hay un ejemplo completo:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     Table("StackOverflowExamples.dbo.Parent"); 

     Id(x => x.ParentId); 
     Map(x => x.FirstName); 
     Map(x => x.LastName); 
    } 
} 

public class OnlyChildOfParentMap : ClassMap<OnlyChildOfParent> 
{ 
    public OnlyChildOfParentMap() 
    { 
     Table("StackOverflowExamples.dbo.OnlyChildOfParent"); 

     CompositeId().KeyReference(x => x.Parent, "ParentId"); 
     Map(x => x.SomeStuff); 
     Map(x => x.SomeOtherStuff); 
    } 
} 

public class Parent 
{ 
    public virtual int ParentId { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
} 

public class OnlyChildOfParent 
{ 
    public virtual Parent Parent { get; set; } 
    public virtual string SomeStuff { get; set; } 
    public virtual string SomeOtherStuff { get; set; } 

    #region Overrides 

    public override bool Equals(object obj) 
    { 
     if (obj == null || GetType() != obj.GetType()) 
      return false; 

     var child = obj as OnlyChildOfParent; 

     if (child != null && child.Parent != null) 
     { 
      return child.Parent.ParentId == Parent.ParentId; 
     } 

     return false; 
    } 

    public override int GetHashCode() 
    { 
     return Parent.ParentId; 
    } 

    #endregion Overrides 
} 
0

Tal vez this mensaje puede ayudar.
He usado la anotación .Cascade.SaveUpdate().
Mi caso fue con un hasOne en el padre poner la anotación en ambos lados

Obs: Idioma PT-BR

+0

Sería útil si pudiera traducir la parte relevante de la respuesta vinculada ... –

Cuestiones relacionadas