2010-09-03 11 views
7

Mam tabeli podrzędnej zawierające identyfikator do rodzica. To jest odwzorowanie jeden do jednego, ale tabela podrzędna może nie mieć wartości. Mam problemy z mapowaniem tego bez otrzymania błędu ... Próbowałem kilku rzeczy; odwzorowujący kolumny, mający różne właściwości itp ..Używanie odniesienia jako identyfikatora w 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.. 

Mapowanie

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"); 

ja jak klasę dziecko nie ma wyraźnego pola ID, ale raczej tylko jako odniesienia do nadrzędnego Może nigdy nie bądź dzieckiem bez rodzica. W bazie danych chcę jednak przechowywać identyfikator rodzica.

Jakieś pomysły, jak mogę to zrobić?

Odpowiedz

5

następujące utwory:

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

tylko do odczytu na odniesienie jest ważne, aby nie uzyskać wyjątek

EDIT: nie było tak proste ...

Moja klasa dziecko jeszcze wywoływana jest właściwość Id. Wygląda na odwołanie Id dla Parent.Id myli nhibernate i próbuje wywołać child.Id zamiast tego. Dodałem następujące do dziecka, a teraz wydaje się, że działa. Całkiem brzydki hack.

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

+1 pracował dla mnie tutaj, ale jest bardziej elegancki sposób to zrobić? –

0

FluentNhibernate API zmienił się na przestrzeni lat, więc nie jestem pewien, czy ta składnia była dostępna, gdy kwestia ta została pierwotnie zapytał, ale można teraz użyć odwołania jako id jeśli map jako kompozytu id. Nie nazwałbym tego hackem, ale to trochę dziwne, że trzeba odwzorować odniesienie do jednostki nadrzędnej jako część złożonego identyfikatora. Oto pełny przykład:

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

Być może this poczta może pomóc.
Użyłem adnotacji .Cascade.SaveUpdate().
Mój przypadek był z hasone w dominującej umieszczenie adnotacji na obu stronach

Obs: Język PT-BR

+0

Pomocne może być przetłumaczenie odpowiedniej części połączonej odpowiedzi ... –

Powiązane problemy