我从未使用延迟加载(使用虚拟关键字),因为一旦我尝试,我发现如果我使用延迟加载会出现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数据,所以我从不使用延迟加载。
但是,当我看到许多教程或博客时,似乎每个人都在使用虚拟关键字?这让我觉得我错过了什么,我觉得我做错了。
你能告诉我我不理解什么,我做错了什么吗?
和
在急切加载时,我们会尽快将所有对象加载到内存中 对象已创建。
我在一些教程中看到,但我认为,除非使用“include”,否则该对象不会加载任何相关数据。
我是对的吗?或者它还加载所有相关的对象?
[编辑,添加更多示例代码]
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();
答案 0 :(得分:0)
在你的案例中有一点我不明白
考虑:
from fd in Folders
select new {
id = fd.IdFolder,
c = fd.Files.Count()
}
使用:
Folder {
/*...*/
public virtual ICollection<File> Files { get; set; }
}
我得到以下SQL:
SELECT
[Extent1].[idDossier] AS [idDossier],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[tableF] AS [Extent2]
WHERE [Extent1].[idDossier] = [Extent2].[idDossier]) AS [C1]
FROM [dbo].[tableD] AS [Extent1]
with(或实际上没有虚拟):
Folder {
/*...*/
public ICollection<File> Files { get; set; }
}
即使使用了以下内容,我也得到了完全相同的查询:
Folders.Include("Files").
Select( fd => new {
id = fd.IdFolder,
c = fd.Files.Count()
})
如果你想要一个连接来获得像:
这样的sqlselect
fd.IdDossier,
count(fl.idDossier)
from
tableD fd
left join tablef fl on fd.IdDossier = fl.idDossier
group by fd.idDossier
我只是不知道该怎么做
from fd in Folders
join fl in Files on fd.IdFolder equals fl.IdFolder into g
select new {
id = fd.IdFolder,
c = g.Count()
}
导致相同的N + 1 SQL