EF在访问导航属性之前执行db查询

时间:2016-10-17 20:15:06

标签: c# entity-framework

当运行下面的代码时,我希望 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

enter image description here

1 个答案:

答案 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);

避免过度获取