2010-12-21 13 views
1

私たちはユーザー、当社システム、です。各ユーザーには多くの人がいます。しかし、ユーザーがログオンしたときに、私たちは住所、彼の名前を記入するために彼の主要人物レコードを検索する必要があり、携帯電話など流暢NHibernate:両方向で1対多の参照を持つ方法?

public class Person 
{ 
    /// <summary>Every Person belongs to a user.</summary> 
    public virtual User User { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual string Address { get; set; } 
    public virtual string Phone { get; set; } 
    // More methods & Properties 
} 

public class User : Entity 
{ 
    public virtual string Username { get; set; } 
    public virtual string Password { get; set; } 
    /// <summary>Every User has a primary person record.</summary> 
    public virtual Person PrimaryPerson { get; set; } 
    // More methods & Properties 
} 

にどのようにクラスマップは、循環参照することなく、このために見えますか?

public class PersonMap : ClassMap<Person> 
{ 
    public PersonMap() 
    { 
     Id(x => x.Id)... 
     ... 
     References(x => x.User).Inverse(); // User references Person 
    } 
} 

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Id(x => x.Id)... 
     ... 
     References(x => x.PrimaryPerson).Column("PrimaryPersonId")... 
     HasMany(x => x.People).KeyColumn("UserId").Inverse(); // UserId is on the Person 
    } 
} 

編集:追加されたテーブルの構造

+0

このように、ユーザーはPersonと1対多の関係を持ち、UserにはPrimary Personがあります。 – Phill

+0

それは正しいです、フィル。 1人のユーザーには多くの人がいます。しかし、その人のうちの1人だけがPrimaryPersonです。 – Rap

+0

おそらく私は何か不足していますが、 'UserMap'の' PersonMap'と 'References(x => x.PrimaryPerson)'に 'References(x => x.User)'を持つことができません。 Hibernateは基本的にこれらが個別の一対多の関係であることを見ています( 'User'は' ICollection SecondaryPersons'を格納していないので、双方向性はありません)。これはあなた自身が制約を実施しなければならないということです。私はこれは循環参照を持っていると思いますが...あなたのドメインクラスもそうです。 – fostandy

答えて

4

これを試してみてください:

public class PersonMap : ClassMap<Person> 
{ 
    public PersonMap() 
    { 
    Table("Persons"); 
    Id(x =>x.Id, "PersonId").GeneratedBy.Identity(); 
    References(x => x.User).Column("UserId").Cascade.All(); 
    Map(x => x.FirstName, "FirstName"); 
    Map(x => x.LastName, "LastName"); 
    Map(x => x.Address, "Address"); 
    Map(x => x.Phone, "Phone"); 
    // More property maps 
    } 
} 

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
    Id(x => x.Id, "UserId").GeneratedBy.Identity(); 
    Map(x => x.Username, "Username"); 
    Map(x => x.Password, "Password"); 
    References<Person>(x => x.PrimaryPerson).ForeignKey("PrimaryPersonId").Cascade.All(); 
    } 
} 

これはあなたのIdsが自動採番していると仮定すると、あなたは、ユーザーを更新するとき、あなたもあなたのPrimaryPersonがそれと一緒に更新したいということです。そうでない場合は、Cascade.All()をCascade.None()に変更します。 PrimaryPersonを手動で更新するか、そうでない場合はSubmitChanges()で「オブジェクトが未保存の一時的インスタンスを参照する」ことを確認してください。

+0

正確に必要なもの。完璧に動作します。ありがとう。 – Rap

0

は、あなたの質問に私のコメントをもとに、私は、マッピングはの線に沿って何かになると思います。


[User] 
UserId 
... -- Other Columns 
PrimaryPersonId -- FK to PersonId in Person table 

[Person] 
PersonId 
... -- Other Columns 
UserId -- FK to UserId in User Table for user has many Persons. 
+0

あなたはHasMany(x => x.People).KeyColumn( "UserId")を参照していると仮定します。 ?これは人の集まりです(プライマリとは無関係です)。私はそれが理にかなっているように、テーブル構造で私の答えを更新します。 – Phill

+0

ありがとう、しかし、私が意味するのは、参照(x => x.User).Inverse();参照(x => x.User).Column( "UserId")。Inverse(); – Rap

+0

ちょっと、私はスキーママッピングを想定しました。あなたのスキーマを使って質問を更新できますか? – Phill

関連する問題