首页 新闻 会员 周边

NHibernate级联(一对多) 子表添加数据失败

1
悬赏园豆:20 [已关闭问题] 关闭于 2011-12-02 17:41

有2个表 WorkForm(one)WorkFormDetail(many)

用NH插入数据的时候无法将数据插入WorkFormDetail

1.WorkForm映射文件

 

WorkForm.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly ="Test.Domain" namespace="Test.Domain.Entities">
<class name="WorkForm" table="WorkForm">
<id name="WorkFormId" column="WorkFormId" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Title" column="Title" type="string" length="100" not-null="true"/>
<property name="Content" column="[Content]" type="string" length="500" not-null="true"/>
<set generic="true" inverse="true" name="WorkFormDetails" table="WorkFormDetail">
<key column="WorkFormId" foreign-key="FK_WorkFormDetail_WorkForm"/>
<one-to-many class="Test.Domain.Entities.WorkFormDetail"/>
</set>
</class>
</hibernate-mapping>

 

2.WorkFormDetail映射文件

 

WorkFormDetail.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly ="Test.Domain" namespace="Test.Domain.Entities">
<class name="WorkFormDetail" table="WorkFormDetail">
<id name="FormDetailId" column="FormDetailId" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Title" column="Title" type="string" length="100" not-null="true"/>
<property name="Content" column="[Content]" type="string" length="500" not-null="true"/>
<many-to-one foreign-key="FK_WorkFormDetail_WorkForm" class="Test.Domain.Entities.WorkForm"
column
="WorkFormId" name="WorkForm"/>
</class>
</hibernate-mapping>

3.WorkForm持久类

WorkForm.cs
public class WorkForm
{
private ISet<WorkFormDetail> _workFormDetails = new HashedSet<WorkFormDetail>();
public virtual int WorkFormId { get; set; }

public virtual string Title { get; set; }

public virtual string Content { get; set; }

public virtual ISet<WorkFormDetail> WorkFormDetails
{
get
{
return _workFormDetails;
}
set
{
_workFormDetails = value;
}
}
}

4.WorkFormDetail持久类

WorkFormDetail.cs
public class WorkFormDetail
{
public virtual int FormDetailId { get; set; }

public virtual string Title { get; set; }

public virtual string Content { get; set; }

public virtual WorkForm WorkForm { get; set; }
}

5.问题来了,下面是插入数据的代码

插入数据的问题代码
protected void Submit_Click(object sender, EventArgs e)
{
string pTitle = txtTitle.Text.Trim();
string pContent = txtContent.Text.Trim();

string cTitle = txtCTitle.Text.Trim();
string cContent = txtCContent.Text.Trim();

WorkForm wf = new WorkForm();
wf.Title = pTitle;
wf.Content = pContent;

WorkFormDetail wfd = new WorkFormDetail();
wfd.Title = cTitle;
wfd.Content = cContent;
wfd.WorkForm = wf;

wf.WorkFormDetails.Add(wfd);

try
{
_session.Save(wf);
_session.Flush();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}

希望有人帮忙看下,一大早上碰到这问题,很纠结...




Kratos Zhang的主页 Kratos Zhang | 初学一级 | 园豆:6
提问于:2011-10-15 11:28
< >
分享
所有回答(3)
0

我的也不行 ,先留个足,解决了告知一下....

H-man | 园豆:205 (菜鸟二级) | 2011-10-18 00:43

嗨你的可以了吗,我的还是不行,是咋回事了

支持(0) 反对(0) 琪琪玉笨笨猪 | 园豆:200 (初学一级) | 2013-11-08 10:30
0

在WorkForm类中添加以下方法:

        ///<summary>
/// 增加一个工作单明细
///</summary>
///<param name="wf"></param>
public virtual void AddWorkFormDetails(WorkFormDetail wf)
{
this.WorkFormDetails.Add(wf);
wf.WorkForm = this;
}

难道这个方法一定要是virtual的吗?去掉virtual关键字就报错.

然后逻辑代码中

            WorkForm wf = new WorkForm();
wf.Title = "title";
wf.Content = "content";

WorkFormDetail wfd = new WorkFormDetail();
wfd.Title = "child title";
wfd.Content = "chile content";

wf.AddWorkFormDetails(wfd);
_session.save(wf);

这样可以级联添加了,怎么感觉和之前的没什么差别呢,但是有添加成功了。。。

Kratos Zhang | 园豆:6 (初学一级) | 2011-10-20 14:38

嗨你的可以了吗,我的还是不行,是咋回事了

支持(0) 反对(0) 琪琪玉笨笨猪 | 园豆:200 (初学一级) | 2013-11-08 13:36

其实没有必要写那个virtual方法,只要把WorkForm.hbm.xml文件中set节点中的inverse="true"换成cascade="all"就可以了,其他的都不需要修改……

支持(0) 反对(0) 谭一丹 | 园豆:200 (初学一级) | 2013-11-28 13:45
0
 public class Order
    {

        public Order()
        {
            this.Items = new Iesi.Collections.Generic.HashedSet<OrderItem>();
            
            //it is ok too
            //this.Items = new List<OrderItem>();
        }

        public virtual Guid ID { get; set; }

        public virtual Iesi.Collections.Generic.ISet<OrderItem> Items { get; set; }
        
        //it is ok too
        //public virtual ICollection<OrderItem> Items { get; set; }

        //public virtual Customer Customer { get; set; }

        public virtual DateTime CreateTime { get; set; }
        public virtual DateTime ModifyTime { get; set; }

        public virtual int Version { get; set; }

        public virtual void AddItem(int amount)
        {
            var now = DateTime.Now;
            var item = new OrderItem() { CreateTime = now, ModifyTime = now, Amount = amount, Order = this };
            this.Items.Add(item);
        }
    }

OrderItem

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Com.Andyshi.NH3.Domain
{
    public class OrderItem
    {
       
        public virtual int Amount { get; set; }

        public virtual Order Order { get; set; }

        //public virtual int Version { get; set; }
        public virtual DateTime CreateTime { get; set; }
        public virtual DateTime ModifyTime { get; set; }

        public override bool Equals(object obj)
        {
            var item = obj as OrderItem;
            return this.Amount == item.Amount
                && this.CreateTime == item.CreateTime
                && this.ModifyTime == item.ModifyTime;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}

Order.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                  assembly="Com.Andyshi.NH3"
                   namespace="Com.Andyshi.NH3.Domain">
  <class name="Order" table="Orders" 
         optimistic-lock="version">
    <id name="ID">
      <generator class="guid"></generator>
    </id>
    <version name="Version" unsaved-value="null"/>
    
    <property name="CreateTime"></property>
    <property name="ModifyTime"/>

    <set name="Items" generic="true" inverse="true" cascade="all" >
      <key column="OrderID" not-null="true"></key>
      <one-to-many class="OrderItem"/>
    </set>
           
  </class>
  
</hibernate-mapping>

OrderItem.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                  assembly="Com.Andyshi.NH3"
                   namespace="Com.Andyshi.NH3.Domain">
  <class name="OrderItem" table="OrderItems"
         optimistic-lock="version"  >
    <composite-id>
      <!--<version name="Version" unsaved-value="null"></version>-->
      <key-property name="Amount"></key-property>
      <key-property name="CreateTime"></key-property>
      <key-property name="ModifyTime"/>
    </composite-id>
    <many-to-one name="Order"
                 column="OrderID"
                 not-null="true"
                 class="Order"
                 ></many-to-one>

  </class>

</hibernate-mapping>

Repository

  public void Add(Order order)
        {
            using (var session = SessionManager.Instance.CreateSession())
            {
                using (var tran = session.BeginTransaction())
                {
                    session.Save(order);

                    tran.Commit();
                }
            }
        }

Test

[Test]
        public void test_add()
        {
            var now = DateTime.Now;
            var order = new Order()
            {
                CreateTime = now,
                ModifyTime = now
            };

            order.AddItem(100);
            order.AddItem(200);


            var repository = new OrderRepository();
            repository.Add(order);

            var orderindb = repository.Get(order.ID);

            Assert.IsNotNull(orderindb);
            
        }
Virus-BeautyCode | 园豆:1619 (小虾三级) | 2013-06-27 17:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册