我想知道如何使用NHibernate 2.1删除一个只具有其ID和类型的实体(如映射中)?
答案 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无论如何都会加载实体。一开始我不喜欢它。然后我意识到了这些优点。如果实体是使用继承,集合或“任何” - 引用的复杂结构的一部分,则实际上更有效。
例如,如果类A
和B
都继承自Base
,则当实际实体属于类型时,它不会尝试删除表B
中的数据A
。如果不加载实际对象,这是不可能的。当有许多继承类型时,这一点尤其重要,这些类型也包含许多附加表。
如果您拥有Base
的集合,则会出现相同的情况,这些集合恰好是A
的所有实例。在内存中加载集合时,NH知道它不需要删除任何B
- 东西。
如果实体A
包含B
s的集合,其中包含C
s(依此类推),则不会尝试删除任何C
s当B
的集合为空时。这只有在阅读集合时才有可能。当C本身很复杂,聚集甚至更多的表等时,这一点尤为重要。
结构越复杂和动态,加载实际数据就越有效,而不是“盲目地”删除它。
HQL删除有陷阱
HQL删除不将数据加载到内存。但是HQL删除并不那么聪明。它们基本上将实体名称转换为相应的表名,并从数据库中删除它。此外,它还会删除一些聚合的收集数据。
在简单的结构中,这可能效果很好而且效率很高。在复杂的结构中,并非所有内容都被删除,导致约束违规或“数据库内存泄漏”。
<强>结论强>
我还尝试用NH优化删除。在大多数情况下,我放弃了,因为NH仍然更聪明,它“只是工作”并且通常足够快。我写的最复杂的删除算法之一是分析NH映射定义并从中构建删除语句。并且 - 毫不奇怪 - 在删除之前不能从数据库中读取数据是不可能的。 (我只是将其缩小为仅加载主键。)