使用NHibernate 2.0.1插入子表

时间:2009-04-17 17:01:02

标签: nhibernate

本周我开始使用NHibernate(挣扎)。我有一个带3个表的小应用程序(我现在使用2个)。表currency和表country这里是映射文件。

<class name="dataprovider.Country,dataprovider" table="country">
    <id name="CountryId" column="country_id" unsaved-value="0">
        <generator class="native"/>
    </id>
    <!--<bag name="BatchList" inverse="true" lazy="true" >
        <key column="country_id" />
        <one-to-many class="Batch" />
    </bag>
    <bag name="PrinterList" inverse="true" lazy="true" >
        <key column="country_id" />
        <one-to-many class="Printer" />
    </bag>-->
    <many-to-one name="CurrencyId" column="currency_id" class="Currency"  cascade="save-update"/>
    <!--<property column="currency_id" name="Currency_Id"/>-->
    <property column="name" name="Name"/>
    <property column="region" name="Region" />
    <property column="comments" name="Comments"/>
</class>

货币映射文件:

<class name="dataprovider.Currency, dataprovider" table="currency">
    <id name="CurrencyId" column="currency_id" >
        <generator class="native"/>
    </id>
    <bag name="CountryList" inverse="true" lazy="true" >
        <key column="currency_id" />
        <one-to-many class="Country" />
    </bag>
    <!--<bag name="DenominationList" inverse="true" lazy="true" >
        <key column="currency_id" />
        <one-to-many class="Denomination" />
    </bag>-->
    <property column="name" name="Name"/>
    <property column="authorizer" name="Authorizer"  />
    <property column="date_created"  name="DateCreated" type="DateTime" not-null="true" />
    <property column="comments"  name="Comments"  />

country持有的多对一关系在Currency持久性类中创建了country类型的属性。现在,当我的测试can_add_currencycan_add_country成功(我导出架构)时,我在字段country的表currency_id中有空值。

这是测试代码:

[Test]
    public void can_add_new_country()
    {
        CountryManager cm = new CountryManager();

        Country country = new Country();
        //country.CurrencyId = CurrencyManager.GetCurrencyById(1);
        country.CurrencyId = new CurrencyManager().GetCurrencyById(1);
        country.Name = "POUND";
        country.Region = "ENGLAND";
        country.Comments = "the comment";

        cm.Add(country);

        using(ISession session = _sessionFactory.OpenSession())
        {
            Country fromdb = session.Get<Country>(country.CountryId);
            Assert.IsNotNull(fromdb);
            Assert.AreNotSame(fromdb, country);
        }
    }

    public Currency GetCurrencyById(int currency_id)
    {//GetCurrencyById from CurrencyManger class
        try
        {
            using(ISession session = NHibernateHelper.OpenSession())
            {
                return session.Get<Currency>(currency_id);

            }
        } catch (Exception ex)
        {
            return null;
        }
    }

问题是:如何使用表格货币中的现有currency_id的currency_id插入表格国家/地区?

你们这些人/女孩怎么做?我被严重困住,一个为期两天的小项目现在花了我一个星期。

2 个答案:

答案 0 :(得分:0)

cascade="save-update"上设置bag name="CountryList"。如果这不起作用,发布CountryManager.Add()的代码可能会有所帮助,看看如何进行储蓄。

在回答第二个问题时,如果我理解正确,这就是NHibernate对待映射集合的方式:

您将集合映射为惰性,因此加载对象将同时加载集合的所有元素。相反,当您第一次访问集合时,NHibernate将查询数据库以填充集合并将其返回。所以,当你第一次做这样的事情时:

var countries = currency.CountryList;

foreach (Country country in currency.CountryList)

NHibernate将默默执行类似于:

的查询
SELECT * FROM country WHERE currency_id = ?

然后构建一个Country对象集合以进行返回(并缓存以便不再运行查询)。

基本上,通过映射文件,您已经告诉NHibernate所有关于您的两个实体(国家和货币)以及它们如何相关,因此它知道如何构建查询以访问数据。同样,它会跟踪集合中的内容,因此当您添加或删除项目时,它可以比较更改的内容并执行相应的INSERT或REMOVE语句。

因此,使用NHibernate映射的集合的方法是使用它们,就像使用普通的.NET集合一样。根据您的意愿添加和删除项目。就在您完成时,请确保告诉NHibernate保留对数据库所做的更改,方法是在添加/删除的每个项目上调用session.Save()session.Delete(),或者(如果已设置级联,就像你一样)在包含集合的父对象上调用session.Save()

答案 1 :(得分:0)

我的级联反而在这方面:

<many-to-one name="CurrencyId" column="currency_id" class="Currency"  cascade="save-update"/>

我改变它之后,即使我重建了解决方案,它仍然没有工作。然后我从Currency_Test类做了另一个测试:can_get_currency_by_id调用相同的函数GetCurrncyById,我可以有一个对象,而can_add_new_country同一个函数返回null。

然后我意识到Country_Test [Setup]Currency_Test的ExportSchema没有按时创建数据库,can_add_new_product有货币对象。这就是它返回null对象的原因。

现在不要滥用;但是你能告诉我如何使用IList<Counrty>CountryList吗?我不知道我是不是很好。根据我的理解,它应该使用相同的country(currency_id引用)存储所有currency个对象。 NHibernate如何做到这一点?