删除父项时,如何使NHibernate删除子引用?

时间:2022-09-07 09:16:27

I have a NewsFeed object mapped as such:

我有一个如此映射的NewsFeed对象:

<class name="NewsFeed">
    <id name="NewsFeedId">
        <generator class="guid"/>
    </id>

    <property name="FeedName" not-null="true" />
    <property name="FeedURL" not-null="true" />
    <property name="FeedIsPublished" not-null="true" />
</class>

And Users who can have a Set of Selected feeds that they might be intereseted in, mapped like so:

并且可以拥有一组他们可能会参与其中的所选Feed的用户,如下所示:

<class name="SystemUser">
    <id name="SystemUserId">
        <generator class="guid"/>
    </id>


    <set name="SelectedNewsFeeds" table="SystemUserSelectedNewsFeeds" cascade="all">
        <key column="SystemUserId" />
        <many-to-many column="NewsFeedId" class="NewsFeeds.NewsFeed, Domain"/>
    </set>

</class>

What I want to happen is when I delete the parent NewsFeed then all of the SelectedNewsFeed references get deleted too, without having to load each SystemUser and delete the NewsFeed by hand.

我想要发生的是当我删除父NewsFeed时,所有SelectedNewsFeed引用也被删除,而不必加载每个SystemUser并手动删除NewsFeed。

What is the best way to achieve this?

实现这一目标的最佳方法是什么?

UPDATE: Using cascade="all-delete-orphan" instead of "all" still results in an exception when deleting the NewsFeed:

更新:使用cascade =“all-delete-orphan”而不是“all”仍然会在删除NewsFeed时导致异常:

The DELETE statement conflicted with the REFERENCE constraint "FKC8B9DF81601F04F4". The conflict occurred in database "System", table "dbo.SystemUserSelectedNewsFeeds", column 'NewsFeedId'.

DELETE语句与REFERENCE约束“FKC8B9DF81601F04F4”冲突。冲突发生在数据库“System”,表“dbo.SystemUserSelectedNewsFeeds”,列'NewsFeedId'中。

3 个解决方案

#1


JMCD

Your second approach:

你的第二种方法:

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

另一种方法是打破中间连接类的多对多关系,nHiberate将能够确定父子关系,并且级联应该有效。

is actually what the nHibernate folks recommend in their documentation.

实际上是nHibernate人员在他们的文档中推荐的内容。

Don't use exotic association mappings.

不要使用异国情调的关联映射。

Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

真正的多对多关联的良好用途很少见。大多数情况下,您需要存储在“链接表”中的其他信息。在这种情况下,使用两个一对多关联到中间链接类要好得多。事实上,我们认为大多数关联是一对多和多对一,在使用任何其他关联风格时应该小心,并问自己是否真的是必要的。

Using two one-to-many associations adds the flexibility to easily add other attributes to the "subscription", such as notification preferences for that particular subscription.

使用两个一对多关联增加了向“订阅”轻松添加其他属性的灵活性,例如该特定订阅的通知首选项。

#2


Since the relation inside the set is many-to-many, nHibernate is not able to tell which end of the relationship is the child and which is the parent, and the quickest way for me to achieve what I wanted was just to write some SQL that I sent through my repository that deleted the respective news feeds from the collection, and then deleted the parent news feed. The next time the collection was hydrated the changes were reflected.

由于集合中的关系是多对多的,nHibernate无法分辨关系的哪一端是子节点,哪个是父节点,而我实现我想要的最快方式就是编写一些SQL我通过我的存储库发送的,从集合中删除了相应的新闻源,然后删除了父新闻源。下次收集水合物时,反映了这些变化。

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

另一种方法是打破中间连接类的多对多关系,nHiberate将能够确定父子关系,并且级联应该有效。

#3


change

cascade="all"

to

cascade="all-delete-orphan"

Reference

#1


JMCD

Your second approach:

你的第二种方法:

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

另一种方法是打破中间连接类的多对多关系,nHiberate将能够确定父子关系,并且级联应该有效。

is actually what the nHibernate folks recommend in their documentation.

实际上是nHibernate人员在他们的文档中推荐的内容。

Don't use exotic association mappings.

不要使用异国情调的关联映射。

Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.

真正的多对多关联的良好用途很少见。大多数情况下,您需要存储在“链接表”中的其他信息。在这种情况下,使用两个一对多关联到中间链接类要好得多。事实上,我们认为大多数关联是一对多和多对一,在使用任何其他关联风格时应该小心,并问自己是否真的是必要的。

Using two one-to-many associations adds the flexibility to easily add other attributes to the "subscription", such as notification preferences for that particular subscription.

使用两个一对多关联增加了向“订阅”轻松添加其他属性的灵活性,例如该特定订阅的通知首选项。

#2


Since the relation inside the set is many-to-many, nHibernate is not able to tell which end of the relationship is the child and which is the parent, and the quickest way for me to achieve what I wanted was just to write some SQL that I sent through my repository that deleted the respective news feeds from the collection, and then deleted the parent news feed. The next time the collection was hydrated the changes were reflected.

由于集合中的关系是多对多的,nHibernate无法分辨关系的哪一端是子节点,哪个是父节点,而我实现我想要的最快方式就是编写一些SQL我通过我的存储库发送的,从集合中删除了相应的新闻源,然后删除了父新闻源。下次收集水合物时,反映了这些变化。

Another alternative is to break the many-to-many relationship with a join class in the middle which nHiberate would be able to determine parent-child relationships and the cascade should work.

另一种方法是打破中间连接类的多对多关系,nHiberate将能够确定父子关系,并且级联应该有效。

#3


change

cascade="all"

to

cascade="all-delete-orphan"

Reference