Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EF、多次选择或使用include时,哪个更好?_C#_Entity Framework - Fatal编程技术网

C# 使用EF、多次选择或使用include时,哪个更好?

C# 使用EF、多次选择或使用include时,哪个更好?,c#,entity-framework,C#,Entity Framework,我有两个实体,一个是盒子,另一个是网球。在tabletennis中有一个外键BoxID,也就是说,tennis必须在框中,而框是tennis的集合 既然我知道了网球ID,我需要检查网球所属的框的名称。我有两个选择 选项A:首先在网球表中找到此网球的属性,获取框ID,然后转到框表以查找框的属性 var tennisId = 12345; // Option A: var tennis = await dbContext.TennisTable .SingleOrDefaultAs

我有两个实体,一个是
盒子
,另一个是
网球
。在table
tennis
中有一个外键
BoxID
,也就是说,
tennis
必须在
框中,而
框是
tennis
的集合

既然我知道了网球ID,我需要检查网球所属的
框的
名称。我有两个选择

选项A:首先在
网球
表中找到此
网球
的属性,获取
框ID
,然后转到
表以查找
的属性

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:

var tennis = await dbContext.TennisTable
        .Include(t => t.Box);
        .SingleOrDefaultAsync(t => t.Id == tennisId);

return tennis.Box.Name;
选项B:直接使用
EF-Core
Include
语法查找
tentiles
及其所属的
框,以获取
框的属性

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:

var tennis = await dbContext.TennisTable
        .Include(t => t.Box);
        .SingleOrDefaultAsync(t => t.Id == tennisId);

return tennis.Box.Name;
在大规模实践中,上述两种方法中哪一种具有更大的性能优势


大规模
意味着在实际用例中问题可能要复杂得多。
盒子
网球
的数量可能是数十亿。

两者都不是。这里不需要
Include
语句

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

我需要核对一下这个网球所属盒子的名称

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

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
logic,您将检索整个网球和拳击场对象。我的答案只检索框名,这大大减少了数据库和应用程序之间的数据传输大小


如果您使用了两个呼叫,您将同时加载网球和拳击对象,您将不得不执行两个呼叫,这意味着由于额外的网络呼叫而增加了数据传输大小降低了性能。

。这里不需要
Include
语句

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

我需要核对一下这个网球所属盒子的名称

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

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
logic,您将检索整个网球和拳击场对象。我的答案只检索框名,这大大减少了数据库和应用程序之间的数据传输大小


如果您使用了两个调用,那么您将同时加载tennis和box对象,您将不得不执行两个调用,这意味着由于额外的网络调用而增加了数据传输大小,并且降低了性能。

定义:
大规模
如果您能够提供一个到多个可能的调用,那将是非常棒的。如果你想用你的代码解决已经存在的问题,那么请发布代码。展望未来在这里是无关紧要的。@FCin:虽然选项应该与代码示例一起给出,但问题不在于如何展望未来,而在于认识到有多种方法可以做到这一点,而不知道哪种方法更好。OP已经完成了提出这两种方法的准备工作。定义:
large-scale
如果您能为许多可能的问题提供解决方案,那就太棒了。如果你想用你的代码解决已经存在的问题,那么请发布代码。展望未来在这里是无关紧要的。@FCin:虽然选项应该与代码示例一起给出,但问题不在于如何展望未来,而在于认识到有多种方法可以做到这一点,而不知道哪种方法更好。OP已经完成了提出这两种方法的准备工作。如果我都需要网球的名字和盒子的名字呢?假设你只需要名字:
。选择(t=>new{BoxName=t.box.name,TennisName=t.N