NHibernate,通过父级添加子项vs将子项设置为父项

时间:2013-04-07 11:09:29

标签: nhibernate fluent-nhibernate nhibernate-mapping

我目前正在开发我的第一个NHibernate项目。

为了测试它我正在构建一个实体图和那个图我尝试坚持到数据库。当我通过IList上的add将子项添加到父项时,插入在数据库中不起作用,因为我在数据库上获得空列异常(代码片段1)

  1. 当我将孩子的引用设置为父级时,它正在工作(虽然这对我来说不自然,请参阅代码段
  2. 这是正常行为还是我做错了什么?
  3. 代码段1:

    var country = new Country();
    var countryLocale = new CountryLocale { LangCode = "nl-nl", Name = "Nederland" };
    country.CountryLocales.Add(countryLocale);
    
    var city = new City();
    var cityLocale = new CityLocale { LangCode = "nl-nl", Name = "Amsterdam" };
    city.CityLocales.Add(cityLocale);
    country.Cities.Add(city);
    

    小组1错误:

      

    无法将值NULL插入“CountryId”列表中   'ArtWorld.dbo.City';列不允许空值。插入   失败。\ r \ n声明已经终止。

    摘录2:

    var country = new Country();
    
    var countryLocale = new CountryLocale { Country = country,LangCode = "nl-nl", 
                                            Name = "Nederland" };
    var city = new City{Country = country};
    
    var cityLocale = new CityLocale { City = city, LangCode = "nl-nl", 
                                            Name = "Amsterdam" };
    
    session.SaveOrUpdate(country);
    

    City and CityLocale地图:

    public class CityMap : ClassMap<City>
    {
        public CityMap()
        {
            Table("City");
            Id(x => x.Id);
            References(x => x.Country).Column("CountryId").Cascade.SaveUpdate();
            HasMany(x => x.CityLocales).KeyColumn("CityId").Cascade.SaveUpdate();
        }
    }
    
    public class CityLocaleMap : ClassMap<CityLocale>
    {
        public CityLocaleMap()
        {
            Table("City_Locale");
            Id(x => x.Id);
            Map(x => x.LangCode).Not.Nullable();
            Map(x => x.Name).Not.Nullable();
            References(x => x.City).Column("CityId").Cascade.SaveUpdate();
        }
    }
    

    这是我的Country / Countrylocale地图:

    public class CountryMap : ClassMap<Country>
    {
        public CountryMap()
        {
            Table("Country");
            Id(x => x.Id);
            HasMany(x => x.Cities).KeyColumn("CountryId").Cascade.SaveUpdate();
            HasMany(x => x.CountryLocales).KeyColumn("CountryId").Cascade.SaveUpdate();
        }
    
    }
    
    public class CountryLocaleMap :ClassMap<CountryLocale>
    {
        public CountryLocaleMap()
        {
            Table("Country_Locale");
            Id(x => x.Id);
            Map(x => x.LangCode).Not.Nullable();
            Map(x => x.Name).Not.Nullable();
            References(x => x.Country).Column("CountryId").Cascade.SaveUpdate();
        }
    }
    

1 个答案:

答案 0 :(得分:4)

NHibernate Mapping更改:

Country方面

  HasMany(x => x.CountryLocales).KeyColumn("CountryId").Cascade.SaveUpdate()

在CountryLocale方面,你有

References(x => x.Country).Column("CountryId").Cascade.SaveUpdate();

其中一个关系应使用.Inverse()标记为反向。

.Cascase.SaveUpdate()确保当临时子项添加到父CountryLocale的{​​{1}}列表时,NHibernate管理子实体Country的生命周期。如果您不想自己明确处理CountryLocale的生命周期,我建议从CountryLocales - &gt;标记多对一方面。 CountryLocaleCountry

您可以通过两种方式在Inverse中使用酸性 来引用Country >直觉

如果国家/地区管理区域设置

CountryLocale中添加一个方法,该方法将管理正在添加的语言环境。客户端(CountryCountry的用户无需明确使用引用)

CountryLocale

CountryLocale更受域驱动

重新定义它,使得public virtual bool AddCountryLocales(CountryLocale locale) { if(!this.CountryLocales.Contains(locale)) { locale.Country =this; this.CountryLocales.Add(locale); return true; } return false; } 没有CountryLocale

Country