如何删除nhibernate中只有id和type的实体?

时间:2009-08-24 16:33:22

标签: nhibernate nhibernate-2

我想知道如何使用NHibernate 2.1删除一个只具有其ID和类型的实体(如映射中)?

1 个答案:

答案 0 :(得分:28)

如果您正在使用延迟加载,则“仅加载”会创建代理。

session.Delete(session.Load(type, id));

使用NH 2.1,您可以使用HQL。不知道它实际上是什么样的,但是这样的事情:请注意这是受SQL注入的 - 如果可能的话,使用参数化查询而不是SetParameter()

session.Delete(string.Format("from {0} where id = {1}", type, id));

修改

对于加载,您无需知道Id列的名称。

如果您需要了解它,可以通过NH元数据获取它:

sessionFactory.GetClassMetadata(type).IdentifierPropertyName

另一个编辑。

session.Delete()正在实例化实体

使用session.Delete()时,NH无论如何都会加载实体。一开始我不喜欢它。然后我意识到了这些优点。如果实体是使用继承,集合或“任何” - 引用的复杂结构的一部分,则实际上更有效。

例如,如果类AB都继承自Base,则当实际实体属于类型时,它不会尝试删除表B中的数据A。如果不加载实际对象,这是不可能的。当有许多继承类型时,这一点尤其重要,这些类型也包含许多附加表。

如果您拥有Base的集合,则会出现相同的情况,这些集合恰好是A的所有实例。在内存中加载集合时,NH知道它不需要删除任何B - 东西。

如果实体A包含B s的集合,其中包含C s(依此类推),则不会尝试删除任何C s当B的集合为空时。这只有在阅读集合时才有可能。当C本身很复杂,聚集甚至更多的表等时,这一点尤为重要。

结构越复杂和动态,加载实际数据就越有效,而不是“盲目地”删除它。

HQL删除有陷阱

HQL删除不将数据加载到内存。但是HQL删除并不那么聪明。它们基本上将实体名称转换为相应的表名,并从数据库中删除它。此外,它还会删除一些聚合的收集数据。

在简单的结构中,这可能效果很好而且效率很高。在复杂的结构中,并非所有内容都被删除,导致约束违规或“数据库内存泄漏”。

<强>结论

我还尝试用NH优化删除。在大多数情况下,我放弃了,因为NH仍然更聪明,它“只是工作”并且通常足够快。我写的最复杂的删除算法之一是分析NH映射定义并从中构建删除语句。并且 - 毫不奇怪 - 在删除之前不能从数据库中读取数据是不可能的。 (我只是将其缩小为仅加载主键。)