我有两个实体,一个是box
,另一个是tennis
。表BoxID
中有一个外键tennis
,也就是说,tennis
必须在box
中,而box
是以下内容的集合tennis
。
现在我知道一个tennis ID
,现在需要检查此name
所属的box
的{{1}}。我有两个选择。
选项A:首先在tennis
表中找到此tennis
的属性,获取tennis
,然后转到BoxID
表以查找以下属性: box
。
box
选项B:直接使用var tennisId = 12345;
// Option A:
var tennis = await dbContext.TennisTable
.SingleOrDefaultAsync(t => t.Id == tennisId);
var box = await dbContext.BoxTable
.SingleOrDefaultAsync(t => t.Id == tennis.BoxID);
return box.Name;
的{{1}}语法查找Include
和它所属的EF Core
,以获取{{1 }}。
tennis
在大规模实践中,以上两种方法中哪一种具有更大的性能优势?
box
意味着在实际用例中,问题可能要复杂得多。 box
和// Option B:
var tennis = await dbContext.TennisTable
.Include(t => t.Box);
.SingleOrDefaultAsync(t => t.Id == tennisId);
return tennis.Box.Name;
的数量可能是数十亿。
答案 0 :(得分:2)
都不是。您在这里不需要Include
语句。
要检索其他相关实体时,应使用Include
语句。但这不是您想要的:
我需要检查一下网球所属的盒子的名称。
您只需要Box
对象即可读取其名称。您不需要加载任何其他实体。
var boxName = db.TennisTable
.Where(t => t.Id == tennisId)
.Select(t => t.Box.Name)
.Single();
如果您需要在不引发异常的情况下说明可能不存在的网球对象,请使用SingleOrDefault()
而不是Single()
。
换句话说:
Where
而不是Single
,EF尚未查询数据库,它可以继续使用IQueryable
。IQueryable
。如果您使用了Include
逻辑,那么您将检索到整个网球和盒子对象。我的答案仅检索框名,这大大减少了数据库和应用程序之间的数据传输大小。
如果您使用了两次通话,则将同时加载网球对象和框对象,您将不得不进行两次通话,这意味着将增加数据传输大小和< / strong>由于额外的网络通话而降低了性能。