nHibernate Cascade AllDeleteOrphan:为什么NH要单独删除每个集合项
本文关键字:删除 集合 单独 AllDeleteOrphan Cascade 为什么 NH nHibernate | 更新日期: 2023-09-27 18:07:01
当我清除这样的childcollection
table.Indizes.Clear();
session.Flush();
则NH为集合中的每个项生成一个delete SQL:
DELETE FROM x_inddef WHERE ind_name = 'IDX_ADRKONZ_CODE' AND tbl_name = ' address 'DELETE FROM x_inddef WHERE ind_name = 'IDX_ADRKUND_EXT' AND tbl_name = ' address '
…
为什么不生成这样的语句?
DELETE FROM x_inddef WHERE tbl_name = 'ADRESSE'
是我的映射有问题,还是这只是正常的行为?
使用流畅映射的简化代码:
public class Table
{
public virtual string Name {get;set;
public virtual IList<Index> Indizes { get; set; }
}
public class TableOverride : IAutoMappingOverride<Table>
{
public void Override(AutoMapping<Table> mapping)
{
mapping.Table("x_tables");
mapping.Id(x => x.Name, "tbl_name");
mapping.HasMany(x => x.Indizes).KeyColumn("tbl_name").Inverse().Cascade.AllDeleteOrphan();
}
}
public class Index
{
public virtual string Name { get; set; }
public virtual Table Table { get; set; }
public override bool Equals(object obj)
{
//...
}
public override int GetHashCode()
{
//...
}
}
public class IndexOverride : IAutoMappingOverride<Index>
{
public void Override(AutoMapping<Index> mapping)
{
mapping.Table("x_inddef");
mapping.CompositeId().
KeyProperty(x => x.Name, "ind_name").
KeyReference(x => x.Table, "tbl_name");
}
}
你应该启用nhibernate的批量更新选项
首先将NHibernate配置中的adonet.batch_size
属性设置为value,大于0。
然后用.BatchSize(xxx)
标记每个hasMany集合
mapping.HasMany(x => x.Indizes)
.BatchSize(25)
.KeyColumn("tbl_name")
.Inverse()
.Cascade.AllDeleteOrphan();
我想这应该有帮助
一次性删除不适用于逆=true。分配一个包含0个元素的索引集合的新实例并取消对旧实例的引用会引发一个异常,因为Nhibernate期望管理该集合。看来唯一的出路就是使用hql。
查看文档中的19.5.4节- http://www.nhforge.org/doc/nh/en/index.html
All-delete-orphan
表示如果删除父元素,则子集合将被删除。
意思是-如果你删除了一个Table
对象,那么DELETE FROM x_inddef WHERE tbl_name =...
将被释放。
调用Clear()
只是删除集合中所有对象的简写,但是Table
对象本身保持不变。
另一个可能的解决方案是使用HQL:
session.CreateQuery("DELETE Index i WHERE i.Table.Name = :tblName")
.SetString( "tblName", "MyTable" )
.ExecuteUpdate();