要展开什么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);
}
}
如果我的回答帮你,请考虑将其标记为“已接受”通过点击其下方的小复选框。如果没有,请让我知道你需要什么进一步的信息,所以我可以帮助你更多。 –