我正在使用NHibernate加载不同类型的大型对象树。映射是使用每子类表策略实现的。我定义了一个基类“Node”,它只有几个字段(NodeId,ParentId,NodeType)和几个从Node继承并添加自己的字段的子类。
这种方法的实施很简单,我不能抱怨性能。使用单个往返,在几百毫秒内在我的旧机器上填充了一个包含10,000个不同类型对象的大树。但是,有一件事让我担心:这样的策略导致生成一个复杂的查询,其中Node表外部连接到与定义的子类相对应的每个其他表。虽然当不同子类的数量很小时这很好,但如果数量增加,OUTER JOIN的复杂性也会增加。
每个类定义表似乎不是一个优雅的选项,并且从基类中选择数据时会很慢(因为UNION)。其他选项似乎增加了到数据库服务器的往返次数。
那么在填充由不同类型的实体组成的大型树时,您认为什么是最佳实践?有没有比table per-subclass更好的东西?
答案 0 :(得分:2)
您在这里处理两个问题:
遍历大型层次结构。
大对象图。
两者都是ORM会遇到麻烦的地方。 ORM将成为瓶颈,因此当您遇到瓶颈时,您可能需要支持标准ORM功能并下拉到存储过程来处理繁重的工作。
使用存储过程,您可以利用SQL的执行计划来解决问题,识别查询慢点并识别索引机会。
来自Nhibernate Documentation(这是一个缓存Nhibernate Forge已关闭)
在瓶颈中使用手工编码的ADO.NET。
在系统的性能关键领域,某些类型的操作 (例如,批量更新/删除)可能 受益于直接的ADO.NET。但 拜托,等到你知道的事情 是一个瓶颈。并且不要假设 直接ADO.NET必然更快。 如果需要直接使用ADO.NET,它 可能值得打开NHibernate ISession并使用该SQL 连接。这样你仍然可以使用 相同的交易策略和 底层连接提供商。
答案 1 :(得分:2)
为防止加入,您可以使用table-per-classhirarchy策略。然后每个子类都驻留在同一个表中,并用鉴别器列进行区分。
我已经将此方法用于15个子类。
唯一的缺点是你不能在子类的属性上定义非null约束,你必须在代码中处理它。