基本上我有一个Topic
对象,可以有多个Category
与之关联。我正在尝试向特定的Category
插入新的Topic
,但我收到错误。
在前端使用ASP.NET 4
,windows-1255
编码,ASP
和hebrew_bin
MySQL
(后端)< / p>
ISession session = dal.GetSession();
using (session.BeginTransaction())
{
Topic t = session.Get<Topic>(topicId);
Category c = new Category() { Name=name };
t.AddCategory(c); // updates both references (inside `t` and inside `c`)
session.Update(t);
session.Save(c);
session.Transaction.Commit();
}
获取错误:
无法插入:[DAL.Models.Category#1] [SQL:INSERT INTO类别(名称,发布,主题ID,ID)值(?,?,?,?)]
最终由于违反外键约束而失败(我猜?
不是有效的ID
):
无法添加或更新子行:外键约束失败(
etladaatdb
。category
,CONSTRAINTFK6482F249B6E2851
FOREIGN KEY(ID
)参考topic
(ID
))
Topic.cs:
public enum ColorEnum { Blue, Red, Green, Yellow }
public class Topic
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual string ImageUri { get; set; }
public virtual ColorEnum Color { get; set; }
public virtual IList<Category> Categories { get; set; }
public virtual void AddCategory(Category c)
{
Categories.Add(c);
c.Topic = this;
}
}
Topic.hbm.xml:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="DAL"
namespace="DAL.Models">
<class name="Topic" lazy="true">
<id name="ID">
<generator class="increment"></generator>
</id>
<property name="Name" />
<property name="Description" />
<property name="ImageUri" />
<property name="Color" type="ColorEnum" />
<bag name="Categories" lazy="true" inverse="true"
batch-size="25" cascade="all-delete-orphan">
<key column="ID" />
<one-to-many class="Category" />
</bag>
</class>
</hibernate-mapping>
Category.cs:
public class Category
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual bool Publish { get; set; }
public virtual Topic Topic { get; set; }
}
Category.hbm.xml:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="DAL"
namespace="DAL.Models">
<class name="Category" lazy="true">
<id name="ID">
<generator class="increment"></generator>
</id>
<property name="Name"/>
<property name="Publish" />
<many-to-one name="Topic" class="Topic" column="TopicID" />
</class>
</hibernate-mapping>
答案 0 :(得分:1)
看起来,您似乎错过了将主题分配到类别。所以这应该做到这一点:
// original
Category c = new Category() { Name=name };
t.AddCategory(c);
// always assign both sides during creation
c.Topic = t;
现在NHibernate将知道引用的 Topic
...并将插入正确的 ID
关于映射。多对一和一对多的关系仅由一列表示。它是子(类别)表中的外键列 - TopicID
。
所以这是正确的映射:
// Topic
<bag name="Categories" lazy="true" inverse="true"
batch-size="25" cascade="all-delete-orphan">
// this is wrong
// <key column="ID" />
// this is the target column in the other table
<key column="TopicID" />
<one-to-many class="Category" />
</bag>
...
// Category
// the same columns for the same relation
<many-to-one name="Topic" class="Topic" column="TopicID" />
有了级联,我们可以保存主题:
session.Update(t);
// not needed, there is a cascade
// session.Save(c);
答案 1 :(得分:0)
我认为您的实体不完整,您应该更改您的代码。
不要忘记对using
个对象使用IDisposable
语句。
using(ISession session = dal.GetSession())
{
using (session.BeginTransaction())
{
Topic t = session.Get<Topic>(topicId);
Category c = new Category() { Name=name };
t.AddCategory(c);
c.Topic = t;
session.SaveOrUpdate(t);
session.Transaction.Commit();
}
}
您也可以使用t.AddCategory(c);
方法:
public void AddCategory(Category category)
{
// add to list
category.Topic = this;
}