如何有效地从自相关表中加载数据
-
29-10-2019 - |
题
考虑以下构建论坛应用的要求
父帖子 通用标签
表结构
tblPost -
- PostId
- ChildPostId
- 标题
- 帖子内容
- 用户名
====================
我可以使用递归CTE检索这类数据。我不确定这是最好的方法。
问题
-
使用SQL检索此数据的最佳方法是什么?
-
是否有更好的方法使用ORM加载此数据?
-
如果执行SQL路由,将数据加载到如下所示的类中的最佳方法是什么:
- Child Post1 - Child Post1-1 - Child Post1-2 - Child Post1-2-1 - Child Post2 - Child Post - Child Post3
-
使用视图的剃刀语法显示这种数据怎么样?
-
解决方案
根据您的评论,您可以提出有关改进当前数据库架构的建议,在这些数据库架构中,您基本上具有post_id
和child_post_id
列来执行分层关系。
让我们继续:
使用SQL检索此数据的最佳方法是什么?
我建议您看看以下文章这说明了一种非常有效的技术,可以非常有效地管理此类分层数据。它使用嵌套集模型,您可以在其中定义带有左右节点的集,然后可以通过单个SQL查询来构建整个树:
![]()
是否有更好的方法使用ORM加载此数据?
有很多使用NHibernate和EF之类的ORM进行此操作的方法,但是我将在下一次讨论。您可能会考虑将您的问题分为多个SO问题,因为该主题非常广泛。如果您学习如何使用普通的ADO.NET进行此操作,您将对所涉及的基础技术有更好的了解,以便明天您决定使用这样的ORM,您将已经知道要查找有效查询的顺序。 / p>
如何使用剃刀语法显示此类数据呢? 视图?
一旦构建了层次模型,它就非常简单。您要做的就是为
Post
类型定义一个自定义显示模板,您将在其中为所有子帖子调用显示模板。因此,假设使用以下模型: 通用标签
和以下控制器(我显然在其中对值进行了硬编码,但在阅读我在文章开头链接的教程之后,您将可以使用单个SQL查询来构建此模型): 通用标签
然后您将拥有一个
~/Views/Home/Index.cshtml
视图: 通用标签,当然还有一个相应的显示模板(
~/Views/Home/DisplayTemplates/Post.cshtml
),在我们的案例中该模板将递归呈现整个树: 通用标签当然,最终结果是人们可能期望的结果:
![]()
更新:
根据评论部分的要求,这是一个如何填充Post模型的示例。假设您已遵循嵌套集模型来设计数据库表: 通用标签
并且您已经用帖子填充了它: 通用标签
现在您可以获取它们。
但是像往常一样做之前,您会描述自己想做的事情。即:您定义合同: 通用标签
现在您要开始做 。在这种情况下,我们将使用普通的ADO.NET查询数据库并构建Post对象。我们将使用带有堆栈的迭代算法来构建树,但您也可以使用递归算法: 通用标签
现在我们有了这个存储库,我们可以将各个部分放在一起: 通用标签
最后一部分是配置您最喜欢的Dependency Injection框架,以注入存储库的所需实现,并且到目前为止,我们只有一个将成为
PostsRepositoryAdoNet
。如果明天决定切换到ORM,您要做的就是编写实现IPostsRepository
接口的相应存储库。