44

基本的な質問: Fluent NHibernate で双方向の 1 対多のマップを作成するにはどうすればよいですか?

詳細:

多くの子を持つ親オブジェクトがあります。私の場合、子に親がないと意味がないので、データベースでは親への外部キーに NOT NULL 制約を持たせたいと考えています。Fluent NHibernate マッピングからデータベースを自動生成しています。

次のような多くの子オブジェクトを持つ親があります。

public class Summary
{
   public int id {get; protected set;}

   public IList<Detail> Details {get; protected set;}
}

public  class Detail
{
   public int id {get; protected set;}

   public string ItemName {get; set;}

  /* public Summary Owner {get; protected set;} */ //I think this might be needed for bidirectional mapping?
}

これが私が始めたマッピングです:

public class SummaryMap : ClassMap<Summary>
{
    public SummaryMap()
    {
        Id(x => x.ID);

        HasMany<Detail>(x => x.Details);
    }
}

public class DetailMap : ClassMap<Detail>
{
    public DetailMap()
    {
        Id(x => x.ID);

        Map(x => x.ItemName).CanNotBeNull();
    }
}

Detail テーブルでは、Summary_id を Not Null にする必要があります。これは、私の場合、Detail オブジェクトがサマリー オブジェクトにアタッチされていないことは意味がないためです。ただし、HasMany() マップを使用するだけでは、Summary_id 外部キーは null 可能のままになります。

NHibernate のドキュメント ( http://www.hibernate.org/hib_docs/nhibernate/html/collections.html ) で、「親が必要な場合は、双方向の 1 対多の関連付けを使用する」ことがわかりました。

では、Fluent NHibernate で双方向の 1 対多マップを作成するにはどうすればよいでしょうか。

4

1 に答える 1

55

Details テーブルの null 以外の外部キー列との双方向の関連付けを取得するには、提案された Owner プロパティである References(...).CanNotBeNull() マッピングを DetailsMap クラスに追加し、Summary エンドを逆にすることができます。

2 つの関連方向に対して 2 つの異なる外部キー列が存在しないようにするには、列名を手動で指定するか、両方の方向に同じ列名を与えるようにプロパティに名前を付けます。この場合、Details.Owner プロパティの名前を Details.Summary に変更することをお勧めします。

現在、サマリーには id 以外の列がないため、テーブルに挿入する際の問題を回避するために、サマリー id をインクリメントで生成しました。

ドメイン:

public class Detail
{
    public int id { get; protected set; }
    public string ItemName { get; set; }

    // Renamed to use same column name as specified in the mapping of Summary.Details
    public Summary Summary {get; set;} 
}

public class Summary
{
    public Summary()
    {
        Details = new List<Detail>();
    }

    public int id { get; protected set; }
    public IList<Detail> Details { get; protected set; }
}

マッピング:

public class DetailMap : ClassMap<Detail>
{
    public DetailMap()
    {
        Id(x => x.id)
            .GeneratedBy.Native();

        Map(x => x.ItemName)
            .CanNotBeNull();

        References<Summary>(x => x.Summary)
            // If you don't want to rename the property in Summary,
            // you can do this instead:
            // .TheColumnNameIs("Summary_id")
            .CanNotBeNull();
    }
}

public class SummaryMap : ClassMap<Summary>
{
    public SummaryMap()
    {
        Id(x => x.id)
            .GeneratedBy.Increment();

        HasMany<Detail>(x => x.Details)
            .IsInverse()
            .AsBag(); // Use bag instead of list to avoid index updating issues
    }
}
于 2008-11-22T09:36:47.347 に答える