1

Posts我正在创建一个包含和的网页Comments。但是,当我在渲染 that 期间检索Commentsfor each时,检索速度非常慢。我的猜测是,这是由于频繁打开/关闭连接。无论如何,它不能很好地扩展。PostPost

为了解决这个问题,我正在考虑将两个实体合并为一个,并PostsComments多态方式进行建模。换句话说,Entry成为一个超类,被Post和子类化Comment

谁能给我一些建议,这是否是一种有效的方法?或者,我愿意接受其他可能也解决我可能没有想到的嵌套Repeater/性能问题的建议。DataList

4

2 回答 2

1

即使您的博客对帖子有数千条评论,它仍然可以正常工作。
RDBMS 表经常会遇到数百万条记录。

频繁打开和关闭连接将成为性能瓶颈。
您应该一次获取所有数据,然后将其传递给您的嵌套中继器。

于 2012-08-30T04:00:11.687 回答
1

扩展 nunespascal 所说的:

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

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

方法 1:迭代加载子项

var posts = db.Posts;
foreach (Post p in posts) {
    Html.Render(p);

    var comments = db.Comments.Where(c => c.PostId == p.PostId);
    foreach (Comment c in comments) {
        Html.Render(c);
    }
}

这听起来像是您在当前的中继器迭代中基本上正在做的事情。对于您来到的每个帖子,加载属于它的评论 - 并将它们呈现出来。

这正是您所描述的瓶颈,您正在打开/关闭大量连接并运行大量单独的原子 SQL 语句。如果可以,请避免这种情况。

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

var posts = db.Posts.Top(10);
// ^ The .Top(10) limits the result-set to a manageable number of posts (10).

var ids = posts.Select(p => p.PostId);
// ^ This line creates an Enumerable list of the IDs of your loaded posts.

var comments = db.Comments.Where(c => ids.Contains(c.PostId));
// ^ This line loads all the comments which belong to the 10 posts you loaded.

foreach (Post p in posts) {
    Html.Render(p);

    foreach (Comment c in comments.Where(c => c.PostId == p.PostId)) {
        // This loop iterates the comments in the same way the previous example
        // showed, with the exception that it iterates *in memory*, rather than
        // running additional SQL on each iteration.
        Html.Render(c);
    }
}

因为您在第二个示例中加载了内存中的所有项目,所以您保存了所有往返行程 - 只创建了 2 个 SQL 语句,这两个语句都在开始时运行。

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

var posts = db.Posts.Include("Comments");
// ^ This line loads both Posts and Comments in a single SQL statement

foreach (Post p in posts) {
    Html.Render(p);

    foreach (Comment c in p.Comments) {
        // EF5 and other ORMs can create a .Comments property which contains an
        // Enumerable list of the comments, already filtered on the FK binding
        Html.Render(c);
    }
}
于 2013-04-18T17:41:11.743 回答