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

mar*_*ark 16 nhibernate nhibernate-2

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

Ste*_*ger 28

如果您使用延迟加载,则"仅加载"会创建代理.

session.Delete(session.Load(type, id));
Run Code Online (Sandbox Code Playgroud)

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

session.Delete(string.Format("from {0} where id = {1}", type, id));
Run Code Online (Sandbox Code Playgroud)

编辑:

对于Load,您不需要知道Id列的名称.

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

sessionFactory.GetClassMetadata(type).IdentifierPropertyName
Run Code Online (Sandbox Code Playgroud)

另一个编辑.

session.Delete() 实例化实体

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

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

当你有一个Bases 的集合时会给出相同的情况,这些集合恰好是所有的实例A.在内存中加载集合时,NH知道它不需要删除任何B-stuff.

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

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

HQL删除有陷阱

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

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

结论

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