【发布时间】:2023-04-01 00:07:02
【问题描述】:
我有这样的实体:
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
//Foreign key for Standard
public int StandardId { get; set; }
public virtual Standard Standard { get; set; }
}
public class Standard
{
public int StandardId { get; set; }
public string StandardName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
在我的查询中,当我写:
dbcontext.Standards.Where(standard => standard.StandardId > 6)
我可以看到已经运行的底层查询是这样的:
SELECT "Extent1"."StandardId", "Extent1"."StandardName"
FROM "dbo"."Standard" as "Extent1"
WHERE "Extent1"."StandardId" > @EntityKeyValue1;
我明白,因为它是 IQueryable,所以即使是 Where 函数中的 Expression 也已被翻译,并且实际上是在数据库中而不是在程序中运行。
由于我已将集合标记为虚拟,因此未加载学生。不,我正在尝试在另一个查询中加载它们:
var XStandard = dbcontext.Standards.Where(standard => standard.StandardId == 10);
var students = XStandard.Students.Where(student => student.StudentId > 5);
我看到执行的查询是:
SELECT "Extent1"."StudentId", "Extent1"."StudentName", "Extent1"."StandardId"
FROM "dbo"."Student" as "Extent1"
WHERE "Extent1"."StandardId = @EntityKeyValue1;
我在该查询中没有看到任何 WHERE 子句检查学生 ID 是否大于 5。它实际上是在获取所有学生并在内存中过滤掉。我知道这是因为它是 IEnumerable 而不是 IQueryable,并且由于 IEnumerable 是 LINQ-to-objects,因此过滤是在内存中完成的。
当我像这样对 dbcontext 运行查询时:
var students = dbcontext.Students.Where(student => student.StudentId > 5 && student.StandardId == 10);
现在 SQL 查询是这样的:
SELECT "Extent1"."StudentId", "Extent1"."StudentName", "Extent1"."StandardId"
FROM "dbo"."Student" as "Extent1"
WHERE "Extent1"."StandardId" = @EntityKeyValue1 AND "Extent1"."StudentId" > @EntityKeyValue2;
如果对嵌套集合的查询获取所有记录而不是少数记录,那么在一对多关系中嵌套集合的意义何在? 有没有办法确保它在数据库端运行?我错过了什么吗?请帮助我了解 EF 在内部是如何工作的。提前致谢。
【问题讨论】:
-
@CamiloTerevinto System.Data.Entity 版本 6.0.0.0
-
您是否关闭了延迟加载?请注意,
dbcontext.Standards.Where(standard => standard.StandardId > 6)不执行查询,只是声明它。除非您关闭了延迟加载,否则使用dbcontext.Standards.Where(standard => standard.StandardId > 6).FirstOrDefault();应该会加载学生集合 -
我已明确开启延迟加载。但是当我尝试访问属性时,查询正在获取整个集合并在程序中进行过滤,而不是在数据库端进行过滤。那么如果有 500 名学生,在应用过滤器后我只想要十几个记录。
标签: c# sql entity-framework entity-framework-6