帮助NHibernate插入/更新

时间:2009-12-24 18:45:34

标签: c# nhibernate

我是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语句,没有插入映射表。

根据我的映射,应该如何保留映射数据?

2 个答案:

答案 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。

再次感谢您的帮助。

约翰