Kev*_*son 8 nhibernate many-to-many nhibernate-mapping
我已经用NHibernate设置了几天,但是我无法找出正确的方法来设置我的映射,所以它的工作方式就像我期望的那样.
在我遇到问题之前需要经过一些代码,所以请提前道歉以获得额外的阅读.
目前的设置非常简单,只有这些表:
类别
CategoryId
名称
Item
ItemId
名称
ItemCategory
ItemId
CategoryId
一个项目可以在许多类别中,每个类别可以有许多项目(简单的多对多关系).
我的映射设置如下:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="..."
namespace="...">
<class name="Category" lazy="true">
<id name="CategoryId" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" />
<bag name="Items" table="ItemCategory" cascade="save-update" inverse="true" generic="true">
<key column="CategoryId"></key>
<many-to-many class="Item" column="ItemId"></many-to-many>
</bag>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="..."
namespace="...">
<class name="Item" table="Item" lazy="true">
<id name="ItemId" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" />
<bag name="Categories" table="ItemCategory" cascade="save-update" generic="true">
<key column="ItemId"></key>
<many-to-many class="Category" column="CategoryId"></many-to-many>
</bag>
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)
我在物品的类别和类别列表中的项目列表中添加项目的方法设置了关系的两侧.
在项目中:
public virtual IList<Category> Categories { get; protected set; }
public virtual void AddToCategory(Category category)
{
if (Categories == null)
Categories = new List<Category>();
if (!Categories.Contains(category))
{
Categories.Add(category);
category.AddItem(this);
}
}
Run Code Online (Sandbox Code Playgroud)
在类别中:
public virtual IList<Item> Items { get; protected set; }
public virtual void AddItem(Item item)
{
if (Items == null)
Items = new List<Item>();
if (!Items.Contains(item))
{
Items.Add(item);
item.AddToCategory(this);
}
}
Run Code Online (Sandbox Code Playgroud)
现在已经不在了,我遇到的问题是:
如果我从Category.Items映射中删除'inverse ="true"',我会在查找ItemCategory表中获得重复的条目.
当使用'inverse ="true"'时,当我尝试删除类别时出现错误,因为NHibernate没有从查找表中删除匹配的记录,因此由于外键约束而失败.
如果我在行李上设置cascade ="all",我可以删除而不会出错但删除类别也会删除该类别中的所有项目.
我的映射设置方式是否存在一些基本问题,以允许多对多映射按预期工作?
通过'你期望的方式',我的意思是删除不会删除任何超过被删除的项目和相应的查找值(使关系的另一端的项目不受影响)和任何集合的更新将更新具有正确和非重复值的查找表.
任何建议都将受到高度赞赏.
tol*_*sm7 10
为了让映射按照您的预期工作,您需要做的是将集合inverse="true"从Category.Items集合移动到Item.Categories集合.通过这样做,你将使NHibernate了解哪一个是关联的拥有方,那将是"类别"方面.
如果这样做,通过删除Category对象,它将根据您的意愿从查找表中删除匹配记录,因为它是关联的拥有方.
为了不删除分配给要删除的Category对象的Items,您需要将cascade attribe留作:cascade="save-update".
cascade="all" 将删除与已删除的类别对象关联的项目.
虽然副作用是删除inverse = tru存在一侧的实体将会产生外键违规异常,因为关联表中的条目未被清除.
使映射完全按照您希望它们工作的解决方案(通过您在问题中提供的描述)将显式映射关联表.你的映射应该是这样的:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="..."
namespace="...">
<class name="Category" lazy="true">
<id name="CategoryId" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" />
<bag name="ItemCategories" generic="true" inverse="true" lazy="true" cascade="none">
<key column="CategoryId"/>
<one-to-many class="ItemCategory"/>
</bag>
<bag name="Items" table="ItemCategory" cascade="save-update" generic="true">
<key column="CategoryId"></key>
<many-to-many class="Item" column="ItemId"></many-to-many>
</bag>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="..."
namespace="...">
<class name="Item" table="Item" lazy="true">
<id name="ItemId" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" />
<bag name="ItemCategories" generic="true" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="ItemId"/>
<one-to-many class="ItemCategory"/>
</bag>
<bag name="Categories" table="ItemCategory" inverse="true" cascade="save-update" generic="true">
<key column="ItemId"></key>
<many-to-many class="Category" column="CategoryId"></many-to-many>
</bag>
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)
如上所述它允许您以下内容:
以上所有都是通过单元测试进行测试的.您需要创建ItemCategory类映射文件和类以使上述工作正常.
| 归档时间: |
|
| 查看次数: |
7082 次 |
| 最近记录: |