为什么一对多在 NHibernate 中不能按预期工作?
我的情况非常简单,真的不知道为什么这不起作用。
这是我的架构:
**[item]**
id (PK)
symbol
**[item_version]**
id (PK)
item_id (FK->ITEM)
symbol
这些是我的映射:
item.hbm.xml
<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="false">
<id name="Id" column="id" type="long">
<generator class="native" />
</id>
<property name="Symbol" column="symbol"/>
<bag name="ItemVersions" lazy="false" table="item_version" inverse="true" cascade="save-update">
<key column="item_id" />
<one-to-many class="Core.Model.Entities.ItemVersion, Core.Model"/>
</bag>
</class>
*item_version.hbm.xml*
<class name="Core.Model.Entities.ItemVersion, Core.Model" table="item_version" lazy="false">
<id name="Id" column="id" type="long">
<generator class="native" />
</id>
<many-to-one name="Item" class="Core.Model.Entities.Item, Core.Model" column="item_id" cascade="save-update"/>
<property name="Symbol" column="symbol"/>
</class>
这些是类:
Item.cs
public class Item : Entity<IItemDao>
{
private long id;
virtual public long Id
{
get { return this.id; }
set { this.id = value; }
}
private string symbol;
virtual public string Symbol
{
get { return this.symbol; }
set { this.symbol = value; }
}
private IList<ItemVersion> item_versions = new List<ItemVersion>();
virtual public IList<ItemVersion> ItemVersions
{
get { return this.item_versions; }
set { this.item_versions = value; }
}
}
ItemVersion.cs
public class ItemVersion : Entity<IItemVersionDao>
{
private long id;
virtual public long Id
{
get { return this.id; }
set { this.id = value; }
}
private Item item = null;
virtual public Item Item
{
get { return this.item; }
set { this.item = value; }
}
private long item_id = 0;
virtual public long ItemId
{
get { return this.item_id; }
set { this.item_id = value; }
}
private string symbol;
virtual public string Symbol
{
get { return this.symbol; }
set { this.symbol = value; }
}
}
而且这段代码......
Item item = new Item();
item.Name = "test";
ItemVersion v = new ItemVersion();
v.Symbol = "test version";
item.ItemVersions.Add(v);
Item.Dao.Save(tmp);
不起作用。它插入一个项目并在插入 item_version 行时引发异常,该 item_version.item_id 不能为 null。因此 NHibernate 不会在 ItemVersion 对象中自动设置 item_id 属性。为什么在这种情况下cascade =“save-update”和inverse =“true”不起作用?
当我手动设置时,通过添加以下代码:
v.Item = item;
然后调用 save,一切正常,但这不是我从 NHibernate 中除外的内容 - 调用
item.ItemVersions.Add(v);
应该足够了。
我做错了什么还是这根本不可能?预先感谢您的回答:)
I have very simple situation and really don't have a clue why this isn't working.
This is my schema:
**[item]**
id (PK)
symbol
**[item_version]**
id (PK)
item_id (FK->ITEM)
symbol
These are my mappings:
item.hbm.xml
<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="false">
<id name="Id" column="id" type="long">
<generator class="native" />
</id>
<property name="Symbol" column="symbol"/>
<bag name="ItemVersions" lazy="false" table="item_version" inverse="true" cascade="save-update">
<key column="item_id" />
<one-to-many class="Core.Model.Entities.ItemVersion, Core.Model"/>
</bag>
</class>
*item_version.hbm.xml*
<class name="Core.Model.Entities.ItemVersion, Core.Model" table="item_version" lazy="false">
<id name="Id" column="id" type="long">
<generator class="native" />
</id>
<many-to-one name="Item" class="Core.Model.Entities.Item, Core.Model" column="item_id" cascade="save-update"/>
<property name="Symbol" column="symbol"/>
</class>
These are the classes:
Item.cs
public class Item : Entity<IItemDao>
{
private long id;
virtual public long Id
{
get { return this.id; }
set { this.id = value; }
}
private string symbol;
virtual public string Symbol
{
get { return this.symbol; }
set { this.symbol = value; }
}
private IList<ItemVersion> item_versions = new List<ItemVersion>();
virtual public IList<ItemVersion> ItemVersions
{
get { return this.item_versions; }
set { this.item_versions = value; }
}
}
ItemVersion.cs
public class ItemVersion : Entity<IItemVersionDao>
{
private long id;
virtual public long Id
{
get { return this.id; }
set { this.id = value; }
}
private Item item = null;
virtual public Item Item
{
get { return this.item; }
set { this.item = value; }
}
private long item_id = 0;
virtual public long ItemId
{
get { return this.item_id; }
set { this.item_id = value; }
}
private string symbol;
virtual public string Symbol
{
get { return this.symbol; }
set { this.symbol = value; }
}
}
And this code...
Item item = new Item();
item.Name = "test";
ItemVersion v = new ItemVersion();
v.Symbol = "test version";
item.ItemVersions.Add(v);
Item.Dao.Save(tmp);
... does not work. It inserts an item and throws an exception while inserting item_version row, that item_version.item_id cannot be null. So item_id property isn't automatically set by NHibernate in ItemVersion object. Why cascade="save-update" and inverse="true" does not work in this case?
When I set manually, by adding this code:
v.Item = item;
and than call save, everything works fine, but this is not what I except from NHibernate - calling
item.ItemVersions.Add(v);
should be sufficient.
Am I doing something wrong or this is simply imposible? Thanks in advance for the answers :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须设置 v.Item,因为 ItemVersions 是
反向
。这意味着“另一方”(多对一)负责维持这种关系。这是标准做法;为了更容易使用,只需向 Item 添加一个方法:
You have to set v.Item because ItemVersions is
inverse
. That means the "other side" (the many-to-one) is in charge of maintaining the relationship.This is standard practice; to make it easier to use just add a method to Item: