2

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

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

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

片段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”;列不允许空值。INSERT 失败。\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);

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

这是我的国家/地区地图:

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

1 回答 1

4

NHibernate 映射更改:

Country你身边

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

在 CountryLocale 方面,您有

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

应使用 将其中一种关系标记为逆关系.Inverse()

.Cascase.SaveUpdate()确保 NHibernate 在将临时子实体添加到父级列表时管理子实体的CountryLocale生命Country周期CountryLocales。如果您不想自己明确处理 CountryLocale 的生命周期,我建议您将多对一方从CountryLocale->标记CountryInverse

有两种方法可以使您的参考Country变得CountryLocale不那么酸眼直观

如果 Country 管理区域设置

添加一个方法Country来管理正在添加的语言环境。一个客户(用户Country并且CountryLocale不需要明确地使用引用)

public virtual bool AddCountryLocales(CountryLocale locale)
{
        if(!this.CountryLocales.Contains(locale))
        {
              locale.Country =this;
              this.CountryLocales.Add(locale);
              return true;  
        }
        return false;
}

CountryLocale 更受域驱动

通过重新定义它,你不能CountryLocale没有 aCountry

public class CountryLocale
{
    public CountryLocale(Country country)
    {
         this.Country = country;
    }

    //you need a no-agrument constructor for NHibernate
    protected CountryLocale()
    {
    }
}
于 2013-04-07T13:23:51.650 回答