使用EF,多次选择或使用包含时哪个更好?

时间:2018-11-07 05:27:02

标签: c# entity-framework

我有两个实体,一个是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; 的数量可能是数十亿。

1 个答案:

答案 0 :(得分:2)

都不是。您在这里不需要Include语句。

检索其他相关实体时,应使用Include语句。但这不是您想要的:

  

我需要检查一下网球所属的盒子的名称。

您只需要Box对象即可读取其名称。您不需要加载任何其他实体。

var boxName = db.TennisTable
                .Where(t => t.Id == tennisId)
                .Select(t => t.Box.Name)
                .Single();

如果您需要在不引发异常的情况下说明可能不存在的网球对象,请使用SingleOrDefault()而不是Single()

换句话说:

  • 查找具有此ID的所有网球对象。我们知道只有一个,但是通过使用Where而不是Single,EF尚未查询数据库,它可以继续使用IQueryable
  • 对于找到的所有条目,选择其框的名称。同样,我们知道只有一个条目,但是EF仍不会实例化查询,因为您尚未枚举IQueryable
  • 取得第一个结果。我们知道这是唯一的结果,但是现在EF将通过单个(组合)调用而不是两个单独的调用访问数据库。

如果您使用了Include逻辑,那么您将检索到整个网球和盒子对象。我的答案仅检索框名,这大大减少了数据库和应用程序之间的数据传输大小。

如果您使用了两次通话,则将同时加载网球对象和框对象您将不得不进行两次通话,这意味着将增加数据传输大小和< / strong>由于额外的网络通话而降低了性能。