NHibernate中Inverse()的作用及父子关系影响解析
NHibernate中
Inverse()的作用、父子关系机制及删除执行顺序解析 1. Inverse()的核心作用
在双向一对多关联里,NHibernate必须明确哪一方负责维护外键关系。Inverse()就是把当前配置的实体(这里是父类City)标记为非维护端,把外键的维护权交给关联的子实体(CityName)。
2. 加与不加Inverse()的父子关系工作机制
加Inverse()(你的当前代码)
- 当你创建
City并往City.CityNames里添加CityName实例,然后保存City:- 第一步:插入
City记录,生成对应的CityID。 - 第二步:插入每个
CityName记录,由CityName自己把外键CityID设为父City的ID。 - 注意:因为
City是非维护端,只修改City.CityNames集合不会触发外键更新,必须同时给CityName设置City属性(子实体的父引用),NHibernate才会识别关系变化。
- 第一步:插入
不加Inverse()
- 此时
City是关系维护端,负责管理CityName的外键CityID:- 第一步:插入
City记录。 - 第二步:插入
CityName记录,这时外键CityID会被设为NULL(因为子实体没维护关系)。 - 第三步:NHibernate额外执行
UPDATE语句,把CityName的CityID更新为父City的ID。 - 这种情况会多一次无效的更新,效率更低;如果
CityID是数据库的非空约束,直接会抛出异常。
- 第一步:插入
3. 删除操作的查询执行顺序
你的配置里同时启用了Cascade.All()和Cascade.AllDeleteOrphan(),结合Inverse()的情况:
- 删除
City实例时,执行顺序是:- 先查询该
City关联的所有CityName记录。 - 删除所有关联的
CityName记录(AllDeleteOrphan会自动删除“孤儿”实体,All包含级联删除规则)。 - 最后删除
City本身的记录。
- 先查询该
- 如果没加
Inverse(),执行顺序大体一致,但可能会先尝试把CityName的外键更新为NULL,不过因为级联规则是AllDeleteOrphan,最终还是会删除子实体,只是多了一次无意义的更新操作。
内容的提问来源于stack exchange,提问作者Abxxx0
相关产品推荐
相关产品推荐

