【发布时间】:2016-06-30 10:40:24
【问题描述】:
我从来没有使用过延迟加载(使用 virtual 关键字),因为一旦我尝试过,我发现如果我使用延迟加载会出现 N+1 问题。
例如,
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
db.Blog.Select(x=> new {
name = x.Name,
postCnt = x.Posts.Count()
}).ToList();
这不会加入表格,查询将与帖子数量一样多。
所以我这样做了,删除 'virtual' 关键字以进行急切加载。然后做
db.Blog.include("Posts").Select(x=> new {
name = x.Name,
postCnt = x.Posts.Count()
}).ToList();
我所有的控制器都返回一个 Json 数据,所以我从不使用延迟加载。
但是,当我看到很多教程或博客时,似乎每个人都在使用 virtual 关键字?这让我觉得我错过了什么,我觉得我做错了什么。
你能告诉我我不理解什么以及我做错了什么吗?
还有,
在急切加载中,我们将所有对象加载到内存中 对象已创建。
我在一些教程中看到了这一点,但我认为,除非使用“包含”,否则该对象不会加载任何相关数据。
我说的对吗?还是加载所有相关的对象?
[已编辑,添加更多示例代码]
public class Post {
public int Id { get; set; }
public int BlogId {get; set;}
public string title { get; set; }
[ForeignKey("BlogId")]
public virtual Blog blog { get; set; }
}
db.Post.Select(x => new {
id = x.id,
blogName = x.Blog.name
}).ToLost();
【问题讨论】:
-
Post的定义是什么?可能是导航问题。 -
@PeterSmith 我添加了 Post 示例代码,你能看一下吗?
-
我不认为你可以通过延迟加载避免 N+1,因为只有 .Include() 可以让你免于其中。延迟加载在某些情况下很好,但对于返回 DTO 的 Web 服务,应该避免它。