流利的NHibernate:如何创建一对多的双向映射? [英] Fluent NHibernate: How to create one-to-many bidirectional mapping?

查看:138
本文介绍了流利的NHibernate:如何创建一对多的双向映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本问题:如何在Fluent NHibernate中创建一个双向的一对多映射?



详细信息: / strong>



我有一个父对象有许多孩子。在我的情况下,孩子没有父母没有意义,所以在数据库中,我希望父母的外键具有NOT NULL约束。我自动生成我的数据库从流利的NHibernate映射。

我有一个像这样的许多子对象的父:

  public class摘要
{
public int id {get; protected set;}

public IList< Detail>详情{get; protected set;}
}

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

public string ItemName {get; set;}

/ * public摘要所有者{get; protected set;} * / /我认为这可能需要双向映射?

$ / code $


这是我开始的映射:

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






在详细信息表中,Summary_id应该不为空,因为在
的情况下,将一个Detail对象不附加到
摘要对象是没有意义的。但是,只使用HasMany()映射会使Summary_id外键可为空。



我在NHibernate文档( http://www.hibernate.org/hib_docs/nhibernate/html/collections.html )如果父母是必需的,使用一个双向的一对多关联。

那么如何在Fluent NHibernate中创建双向的一对多映射?

解决方案

要获取与Details表中的非空外键列的双向关联,您可以添加建议的Owner属性,References(... ).CanNotBeNull()在DetailsMap类中进行映射,并使摘要反转。



为了避免在两个关联方向上有两个不同的外键列,手动指定列名称或以给出两个方向的相同列名的方式命名属性。在这种情况下,我建议将Details.Owner属性重命名为Details.Summary。

我使用Increment生成的Summary id,以避免从Summary currenty除id以外没有列。



域名:
$ b

  public class详细
{
public int id {get;保护组}
public string ItemName {get;组; }

//重命名为使用Summary.Details映射中指定的相同列名称
public Summary Summary {get; ()









$ b { ;
}

public int id {get;保护组}
public IList< Detail>详情{get;保护组}

映射:

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

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

参考文献< Summary>(x => x.Summary)
//如果你不想重命名Summary,
//你可以这样做相反:
//.TheColumnNameIs(Summary_id)
.CanNotBeNull();
}
}

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

HasMany< Detail>(x => x.Details)
.IsInverse()
.AsBag(); //使用包而不是列表来避免索引更新问题




$ b

Basic question: How to I create a bidirectional one-to-many map in Fluent NHibernate?

Details:

I have a parent object with many children. In my case, it is meaningless for the child to not have a parent, so in the database, I would like the foreign key to the parent to have NOT NULL constraint. I am auto-generating my database from the Fluent NHibernate mapping.

I have a parent with many child objects like so:

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?
}

Here is the mapping I started with:

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();
    }
}

In the Detail table, the Summary_id should be Not Null, because in my case it is meaningless to have a Detail object not attached to the summary object. However, just using the HasMany() map leaves the Summary_id foreign key nullable.

I found in the NHibernate docs (http://www.hibernate.org/hib_docs/nhibernate/html/collections.html) that "If the parent is required, use a bidirectional one-to-many association".

So how do I create the bidirectional one-to-many map in Fluent NHibernate?

解决方案

To get a bidirectional association with a not-null foreign key column in the Details table you can add the suggested Owner property, a References(...).CanNotBeNull() mapping in the DetailsMap class, and make the Summary end inverse.

To avoid having two different foreign key columns for the two association directions, you can either specify the column names manually or name the properties in a way that gives the same column name for both directions. In this case you I suggest renaming the Details.Owner property to Details.Summary.

I made the Summary id generated by increment to avoid problems when inserting into the table since Summary currenty has no columns besides id.

Domain:

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; }
}

Mapping:

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
    }
}

这篇关于流利的NHibernate:如何创建一对多的双向映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆