我是NHibernate的新手并且发现它非常有趣。我一直在尝试将对象持久化到映射表(在关系数据库设计中打破多对多关系的表)但到目前为止还没能这样做。不过,我能够使用当前的hibernate-mapping从映射表中检索数据。
以下是我的数据库:
群组(groupId,groupName) 报告(reportID,reportName) GroupReports(groupId,reportId)
在数据建模方面非常典型和简单的关系。
我知道这个问题已被多次询问,我已经阅读了很多这些问题。相信我,我真的做到了。
这是我的Group实体类的映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.Group, DataTransfer" table="GROUPS">
<id name="GroupId">
<column name="groupId" sql-type="int" not-null="true"/>
<generator class="native"/>
</id>
<property name="GroupName" column="groupName" type ="string" length="150" not-null="true"/>
<bag name="Reports" cascade="none" inverse="true">
<key column="groupId"/>
<many-to-many column="reportId" class="DataTransfer.Report, DataTransfer"/>
</bag>
</class>
</hibernate-mapping>
我对Report实体类的映射如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.Report, DataTransfer" table="REPORTS" >
<id name="ReportId" column="reportId" type="int" unsaved-value="0">
<generator class="native"/>
</id>
<property name = "ReportName" column="reportName" type="string" length="250" not-null="true"/>
<bag name="MappedGroups" table="GroupReports" cascade="all" inverse="false" lazy="true">
<key column="reportId"/>
<many-to-many class="DataTransfer.Group, DataTransfer" column="groupId" />
</bag>
</class>
</hibernate-mapping>
根据我读过的内容,这些映射应该允许我从关联表GroupReports中检索和持久化映射数据。我的单元测试代码只显示选择的SQL语句,没有插入映射表。
根据我的映射,应该如何保留映射数据?
答案 0 :(得分:1)
假设您正确设置了sessionfactory / session(因为您正在获取SELECT语句),我敢打赌您没有使用事务或刷新会话。
在NHibernate中更新数据的推荐方法是始终使用事务。像这样:
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction())
{
var group = new Group {GroupName="Programmers Anonymous"};
session.Save(group);
tx.Commit();
}
这应该让你去。
- UPDATE -
所以在阅读完其他问题之后,好像你想要这个代码......
session.Save(report);
也可以自动保留组。但是在映射中,您已将组集合定义为cascade="none"
。将其更改为cascade="save-update"
,它将解决此问题。
希望这能解决你的问题。
答案 1 :(得分:0)
谢谢Ben,你的回复。直到今天我才能找到我的帖子。 : - 。)
实际上我确实在我的代码中使用了事务。这是我的Add方法的代码:
public int Add(Report obj)
{
//set the flush mode to Never so that session.save() does not cause a flush until the commit()
//on transaction is called
_session.FlushMode = FlushMode.Never;
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(obj);
tx.Commit();//this will cause the a flush of the session
return newId;
}
catch (HibernateException)
{
tx.Rollback();
throw;
}
}
}
我可以使用此代码保存父对象。在我的情况下,我能够将Report对象持久化到数据库。这是我的单元测试代码,用于通过使用多对多关系映射来保存父对象和子对象:
const string reportCd = "TE";
const string reportName = "Test Report 6";
Report report = new Report;
report.ReportCd = reportCd;
report.ReportName = reportName;
report.IsPublicFlag = 0;
IList<Group> groups = new List<Group>();
Group group = new Group();
group.GroupId = 2;
groups.Add(group);
report.Groups = Groups;
_provider.Add(report);
_provider对象是我的Dao对象,它具有上面提到的Add方法。
此外,由于报告和组是多对多对象,因此它们包含彼此的IList。 Report对象的Groups是Group对象的IList,Group对象有一个Reports IList。
再次感谢您的帮助。
约翰