Inheritance 使用NHibernate从数据库填充大型树时的表/子类策略

Inheritance 使用NHibernate从数据库填充大型树时的表/子类策略,inheritance,nhibernate,table-per-class,Inheritance,Nhibernate,Table Per Class,我正在使用NHibernate加载一个由不同类型的对象组成的大型树。映射是使用每个子类的表策略实现的。我定义了一个基类“Node”,它只有几个字段(NodeId、ParentId、NodeType)和几个从Node继承并添加自己字段的子类 这种方法的实现非常简单,我不能抱怨性能。一个包含10000个不同类型对象的大型树在几百毫秒内通过一次往返在我的旧机器上填充。然而,有一件事让我担心:这种策略会导致生成一个复杂的查询,其中节点表与定义的子类对应的每个其他表进行外部连接。当不同子类的数量较少时,这

我正在使用NHibernate加载一个由不同类型的对象组成的大型树。映射是使用每个子类的表策略实现的。我定义了一个基类“Node”,它只有几个字段(NodeId、ParentId、NodeType)和几个从Node继承并添加自己字段的子类

这种方法的实现非常简单,我不能抱怨性能。一个包含10000个不同类型对象的大型树在几百毫秒内通过一次往返在我的旧机器上填充。然而,有一件事让我担心:这种策略会导致生成一个复杂的查询,其中节点表与定义的子类对应的每个其他表进行外部连接。当不同子类的数量较少时,这是可以的,但如果数量增加,外部连接的复杂性也会增加

按类定义表似乎不是一个优雅的选项,从基类中选择数据时,它的工作速度会很慢(因为UNION)。其他选项似乎会增加到数据库服务器的往返次数


那么,当填充由不同类型的实体组成的大型树时,您认为什么是最佳实践?每个子类有什么比table更好的吗?

您在这里处理两个问题:

  • 遍历大型层次结构

  • 大型对象图

  • 这两个领域的ORMs都会遇到麻烦。ORM将成为这里的瓶颈,因此当遇到瓶颈时,您可能需要绕过标准ORM功能,转而使用存储过程来处理繁重的工作

    使用存储过程,您可以利用SQL的执行计划来解决问题、确定查询的慢点以及确定索引机会

    从(这是Nhibernate Forge关闭的缓存)

    在瓶颈中使用手工编码的ADO.NET

    在系统的性能关键区域,某些类型的操作 (例如,大规模更新/删除)可能 受益于DirectADO.NET。但是 请等你知道些什么 这是一个瓶颈。别这么想 direct ADO.NET必然更快。 如果需要使用direct ADO.NET,则 也许值得开一家NHibernate ISession并使用该SQL 连接。这样你仍然可以使用 相同的事务策略和 基础连接提供程序


    为了防止联接,可以使用表每类hirarchy策略。然后,每个子类都驻留在同一个表中,并使用鉴别器列进行鉴别

    我已经对15个子类使用了这种方法


    唯一的缺点是你不能在子类的属性上定义NOTNULL约束,你必须在代码中处理它。

    +1一个好问题,我正在设计一个可能有20个子类型的系统,我有同样的问题。