Fluent NHibernate/フルーエントマッピング/自己参照

提供: MonoBook
ナビゲーションに移動 検索に移動

Fluent NHibernate自己参照を記述する方法。

エンティティ

Parentプロパティが「protected set」となっている点が見どころ。 Fluent NHibernateの古いバージョンでは「private set」でも行けたようだが、最新バージョンではエラーとなるので注意すること。

public class TreeNode
{
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
    public virtual TreeNode Parent { get; protected set; }
    public virtual IList<TreeNode> Childs { get; set; }

    public TreeNode()
    {
        this.Childs = new List<TreeNode>();
    }
}

マッピング

マッピングでの見どころはParentのカラム名を明示しているところ。 References関数で参照設定した場合、Column関数で明示しないと「TreeNode_Id1」など自動的にカラム名が割り振られ、あとから手動で追っかけれなくなるためである。

次に子ノード群をHasMany関数でリレーションであることを明示し、KeyColumn関数で引っ張ってくるキーを明示的に指定する。

public class CustomerMap : ClassMap<TreeNode>
{
    public CustomerMap()
    {
        Id(x => x.Id)
            // 自動インクリメントは.GeneratedBy.Increment()とよく間違うが
            // .GeneratedBy.Identity()が正解。実に紛らわしい。
            // もしかするとDBエンジンによっては違うのかもしれない。未調査。
            .GeneratedBy.Identity()
            ;
        
        Map(x => x.Name)
            .Not.Nullable() // NOT NULL
            .Length(255)    // VARCHAR(255)となる。
                            // 長さに応じてVARCHARやTEXTは自動的に切り替わる。
            ;

        // 親ノードのカラム名を明示しておく
        References(x => x.Parent)
            .Column("ParentId")
            ;

        // 子ノードたちは親ノード名をキーに引っ張ってくることを明示する
        HasMany(x => x.Childs)
            .Cascade.All()  // 外部キー制約をつけて更新を連動させるようにしておく。地味に重要。
            .KeyColumn("ParentId") // キーカラムを指定する。
            ;
    }
}

関連項目

参考文献


外部リンク