本周我开始使用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_currency
和can_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插入表格国家/地区?
你们这些人/女孩怎么做?我被严重困住,一个为期两天的小项目现在花了我一个星期。
答案 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如何做到这一点?