[英]When Include() executing in Entity Framework?
我有一个简单的问题,但没有找到答案。
如果我这样做
var result = _db.Table.Include(t => t.Child).Where(t => t.Id == id).Single();
join
什么时候打电话? 在找到我的实体之后,或者它包括SQL期间的每个孩子都在寻找行?
让我们看一下基于简单数据库模型的示例:
public class Head
{
//... columns
public virtual Child {get; set;}
public Guid? ChildId {get; set;}
}
void main()
{
//The first version of code
var child = _db.Head.Include(h => h.Child)
.FirstOrDefault(//boring staff but we don't need child here)
?.Child;
if (child != null)
foo(child);
//The second one
var head = _db.Head.FirstOrDefault(//boring staff);
if (head != null && head.ChildId.HasValue)
foo(head.Child); // I know here we make a new request to our db
}
两种选择中哪个更有效? 当我仅需要基于父表的过滤器查询的一个对象时,我担心“通过SQL加载额外的子对象”。
提前致谢!
它将首先评估条件。 不是在C#中,而是在生成的SQL中。 这将生成类似
SELECT top 1 .... FROM Table t
JOIN Child c ....
WHERE t.Id = id
您的数据库服务器将创建一个执行计划,该计划将在索引中查找项目并获得相应的子项。
如果没有Include
则将延迟加载Child
对象,直到需要它们为止。 因此,如果您要像这样迭代父/子组
foreach (var parent in _db.Table.Include(t => t.Child).Where(p => p.Name.StartsWith("Q")))
foreach (var child in parent.Child)
Console.WriteLine($"{child}, child of {parent}");
往返次数等于父母人数加一。
如果使用Include
,则将所有Child
对象与父对象一起加载,而无需为每个父对象进行单独的往返。 因此,以上代码的数据库往返次数将等于1。
在Single
的情况下,可以如下重写
var result = _db.Table.Include(t => t.Child).Single(t => t.Id == id);
往返次数将为1( Include
和2(不Include
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.