SQL和ASP.net中的层次结构

SQL和ASP.net中的层次结构,asp.net,sql,sql-server,ado.net,hierarchical-data,Asp.net,Sql,Sql Server,Ado.net,Hierarchical Data,我正在创建一个网页,其中包含帖子和评论。但是,当我在呈现Post期间为每个Post检索注释时,检索速度非常慢。我猜这是由于频繁打开/关闭连接造成的。不管怎样,它不能很好地扩展 为了解决这个问题,我正在考虑将两个实体合并为一个实体,并以一种多形的方式对帖子和评论进行建模。换句话说,Entry成为一个超类,由Post和Comment进行子类划分 有谁能给我一些建议,看看这是不是一个有效的方法?或者,我愿意接受其他建议,这些建议也可能会解决嵌套的转发器/数据列表性能问题,这可能是我没有想到的。即使你的

我正在创建一个网页,其中包含
帖子
评论
。但是,当我在呈现
Post
期间为每个
Post
检索
注释时,检索速度非常慢。我猜这是由于频繁打开/关闭连接造成的。不管怎样,它不能很好地扩展

为了解决这个问题,我正在考虑将两个实体合并为一个实体,并以一种多形的方式对
帖子
评论
进行建模。换句话说,
Entry
成为一个超类,由
Post
Comment
进行子类划分


有谁能给我一些建议,看看这是不是一个有效的方法?或者,我愿意接受其他建议,这些建议也可能会解决嵌套的
转发器
/
数据列表
性能问题,这可能是我没有想到的。

即使你的博客上有数千条评论,它仍然可以正常工作。
RDBMS表通常会运行到数百万条记录中

频繁打开和关闭连接将成为性能瓶颈。

您应该一次获取所有数据,然后将其传递给嵌套的中继器。

要详细介绍nunespascal所说的内容:

无论您是通过两个单独的表将数据作为两个单独的实体拉回来,还是以多态方式从同一个表中拉回来,听起来您遇到的问题似乎是如何请求数据

在C#-ish EF伪代码中考虑以下两种方法:

方法1:迭代加载子项

var posts=db.posts;
foreach(职位p中的职位){
Html.Render(p);
var comments=db.comments.Where(c=>c.PostId==p.PostId);
foreach(注释中的注释c){
Html.Render(c);
}
}
这听起来像是您在当前repeater迭代中正在做的事情。对于你看到的每一篇文章,加载属于它的评论,并呈现出来

这恰恰造成了您所描述的瓶颈,您正在打开/关闭许多连接,并运行许多独立的原子SQL语句。尽可能避免这种情况

方法2:将父母/子女一起加载

var posts=db.posts.Top(10);
//^Top(10)将结果集限制为可管理的帖子数(10)。
var id=posts.Select(p=>p.PostId);
//^此行创建加载帖子ID的可枚举列表。
var comments=db.comments.Where(c=>ids.Contains(c.PostId));
//^此行加载属于您加载的10篇文章的所有评论。
foreach(职位p中的职位){
Html.Render(p);
foreach(comments.Where(c=>c.PostId==p.PostId)中的注释c){
//此循环以与上一示例相同的方式迭代注释
//显示,除了它在内存中迭代*,而不是
//在每次迭代中运行额外的SQL。
Html.Render(c);
}
}
因为在第二个示例中,您正在加载内存中的所有项,所以保存了所有往返-只生成2条SQL语句,这两条语句都在开始时运行

如果您实际使用的是EF4/5(上面的代码基于此),那么您甚至可以执行以下操作:

var posts=db.posts.Include(“评论”);
//^此行在一条SQL语句中加载帖子和评论
foreach(职位p中的职位){
Html.Render(p);
foreach(注释p.注释中的注释c){
//EF5和其他ORM可以创建.Comments属性,该属性包含
//注释的可枚举列表,已在FK绑定上过滤
Html.Render(c);
}
}

< /代码>如果我的答案帮助了你,请考虑通过点击它的分数下面的小复选框将它标记为“接受”。如果没有,请让我知道你需要什么进一步的信息,这样我可以帮助你更多。