当我清理像这样的儿童集合时
table.Indizes.Clear();
session.Flush();
然后NH为集合中的每个项目生成一个删除SQL:
DELETE FROM x_inddef WHERE ind_name ='IDX_ADRKONZ_CODE'AND tbl_name ='ADRESSE' DELETE FROM x_inddef WHERE ind_name ='IDX_ADRKUND_EXT'AND tbl_name ='ADRESSE'
...
为什么不生成这样的声明?
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");
}
}
答案 0 :(得分:3)
您应该使用nhibernate
启用批量更新选项首先将NHibernate配置中的adonet.batch_size
属性设置为value,大于零。
然后使用.BatchSize(xxx)
mapping.HasMany(x => x.Indizes)
.BatchSize(25)
.KeyColumn("tbl_name")
.Inverse()
.Cascade.AllDeleteOrphan();
我想这应该有帮助
答案 1 :(得分:1)
一次性删除不适用于inverse = true。使用0个元素分配索引集合的新实例并解除引用旧元素会抛出异常,因为Nhibernate期望管理集合。似乎唯一的出路就是使用hql。
检查文档中的第19.5.4节 - http://www.nhforge.org/doc/nh/en/index.html
答案 2 :(得分:0)
All-delete-orphan
表示如果删除父元素,将删除您的子集合
意思是 - 如果删除Table
对象,则会发出DELETE FROM x_inddef WHERE tbl_name =...
调用Clear()
只是删除集合中所有对象的简写,但Table
对象本身保持不变。
答案 3 :(得分:0)
另一种可能的解决方案是使用HQL:
session.CreateQuery("DELETE Index i WHERE i.Table.Name = :tblName")
.SetString( "tblName", "MyTable" )
.ExecuteUpdate();