[英]Which is better when using EF, select multiple times or using include?
I have two entities, one is box
and the other is tennis
. 我有两个实体,一个是
box
,另一个是tennis
。 There is a foreign key BoxID
in table tennis
, that is to say, a tennis
must be in a box
, and the box
is a collection of tennis
. tennis
有一个外键BoxID
,也就是说, box
必须装有tennis
,而box
是tennis
的集合。
Now that I know a tennis ID
, I need to check the name
of the box
to which this tennis
belongs. 现在我知道了
tennis ID
,我需要检查该tennis
所属的box
的name
。 I have two options. 我有两个选择。
Option A: First find the attribute of this tennis
in the tennis
table, get the BoxID
, and then go to the box
table to find the attribute of the box
. 选项A:首先找到这个的属性
tennis
在tennis
表,拿到BoxID
,然后转到box
表中查找的属性box
。
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;
Option B: Directly use the Include
syntax of EF Core
to find the tennis
and the box
to which it belongs, to get the properties of the box
. 选项B:直接使用
EF Core
的Include
语法查找tennis
及其所属的box
,以获取box
的属性。
// Option B:
var tennis = await dbContext.TennisTable
.Include(t => t.Box);
.SingleOrDefaultAsync(t => t.Id == tennisId);
return tennis.Box.Name;
In the large-scale practice, which of the above two methods has more performance advantages? 在大规模实践中,以上两种方法中哪一种具有更大的性能优势?
large-scale
means that the questions may be much more complicated in real use cases. large-scale
意味着问题在实际用例中可能要复杂得多。 The count of box
and tennis
may be billions. 的计数
box
和tennis
可能是数十亿美元。
Neither. 都不行 You don't need an
Include
statement here. 您不需要在此处
Include
语句。
The Include
statement should be used when you want to retrieve additional related entities . 要检索其他相关实体时,应使用
Include
语句。 But that is not what you want: 但这不是您想要的:
I need to check the name of the box to which this tennis belongs.
我需要检查此网球所属的框的名称。
You only need the Box
object to read its name. 您只需要
Box
对象来读取其名称。 You don't need to load any additional entities. 您不需要加载任何其他实体。
var boxName = db.TennisTable
.Where(t => t.Id == tennisId)
.Select(t => t.Box.Name)
.Single();
If you need to account for the tennis object possibly not existing without throwing an exception, use SingleOrDefault()
instead of Single()
. 如果需要在不引发异常的情况下考虑可能不存在的网球对象,请使用
SingleOrDefault()
而不是Single()
。
In other words: 换一种说法:
Where
instead of Single
, EF does not yet query the database and it can keep using an IQueryable
instead. Where
而不是Single
,EF尚未查询数据库,它可以继续使用IQueryable
。 IQueryable
yet. IQueryable
。 If you had used Include
logic, you would've retrieved the entire tennis and box objects. 如果使用了“
Include
逻辑,则将检索到整个网球和框对象。 My answer only retrieves the box name, which is a significant reduction of data transfer size between the database and your application. 我的答案仅检索框名,这大大减少了数据库和应用程序之间的数据传输大小。
If you had used two calls, you would've loaded both the tennis and box object and you would've had to do two calls, which means increased data transfer size and lowered performance due to additional network calls. 如果使用了两次通话,则将同时加载网球对象和盒子对象, 并且必须进行两次通话,这意味着由于进行了额外的网络通话,因此增加了数据传输大小并降低了性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.