当运行下面的代码时,我希望 EF 在达到第3行时执行数据库查询,然后在<延迟加载时执行第二次数据库查询<达到强>第6行。但是,当我使用调试器逐步执行代码时, SQL Server Profiler 显示查询在第3行(按预期)和第5行执行!
这怎么可能?为什么在第6行访问导航属性之前执行第二个查询?
1. using (var context = new Entities())
2. {
3. var studentList = context.Students.ToList<Student>();
4. var student = studentList.ElementAt<Student>(1);
5. student.StudentName = "Zorro";
6. var standard = student.Standard;
7. }
查询1:
SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId],
[Extent1].[RowVersion] AS [RowVersion]
FROM [dbo].[Student] AS [Extent1]
查询2:
exec sp_executesql N'SELECT
[Extent1].[StandardId] AS [StandardId],
[Extent1].[StandardName] AS [StandardName],
[Extent1].[Description] AS [Description]
FROM [dbo].[Standard] AS [Extent1]
WHERE [Extent1].[StandardId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=2
答案 0 :(得分:0)
这个问题代表了我讨厌延迟加载的一切。它很容易做到这样的事情并执行两个查询而没有注意到,一个人会做得很好。延迟加载很容易错过这个。
IMO你应该把它关掉。
如果您想确保在原始数据库查询中获得Standard
,您应该像这样急切加载它:
var studentList = context.Students.Include(x=>x.Standard).ToList<Student>();
一方面,这不会打算拉下整个学生名单,你可能想要:
var student = context.Students.Include(x=>x.Standard).FirstOrDefault();
或
var student = context.Students.Include(x=>x.Standard).SingleOrDefault(x=>x.Id == 1);
避免过度获取