gpt4 book ai didi

c# - Entity Framework Core 3.0 包含集合导航属性对性能的影响(笛卡尔爆炸)

转载 作者:行者123 更新时间:2023-12-02 01:30:28 26 4
gpt4 key购买 nike

将 EF Core 2.2 升级到 EF Core 3.0 后,我们遇到了重大性能问题。想象一个简单的数据模型,具有单个集合导航属性和数百个字段(现实看起来更加黑暗):

public class Item
{
[Key]
public int ItemID {get;set;}

public ICollection<AddInfo> AddInfos {get;set;}
... // consisting of another 100+ properties!
}

public class AddInfo
{
[Key]
public int AddInfoID {get;set;}
public int? ItemID {get;set;}
public string SomePayload {get;set;}
}

在项目检索期间,我们查询如下:

...
var myQueryable = this._context.Items.Include(i => i.AddInfos).Where(**some filter**);
... // moar filters
var result = myQueryable.ToList();

直截了当,到目前为止。

在 EF 2.2 中,获取可查询结果会产生两个单独的查询,一个针对 Item,另一个针对 AddInfo 级别。这些查询通常会获取 10,000 个 items 和大约 250,000 个 AddInfos

但是,在 EF Core 3.0 中,会生成单个查询,将 AddInfo 左连接到 Item,乍一看似乎是更好的选择。然而,我们的 Item 需要使用所有 100 多个字段来获取,这就是为什么无法投影到较小的类或匿名类型(添加对 .Select(...) 方法的调用)的原因可行的。因此,结果集中有太多冗余(每个 Item 大约 25 次),以至于查询本身需要很长时间才能在可接受的时间内运行。

EF-Core 3.0 是否提供任何选项,使我们能够切换回旧版 EF Core 2.2 时代的查询行为,无需对数据模型进行大量更改?我们已经从应用程序其他部分的这一更改中受益,但在这个特定场景中却没有。

非常感谢!

更新

经过进一步调查,我发现 Microsoft here 已经解决了这个问题。并且开箱即用,似乎无法配置拆分查询执行。

最佳答案

根据我最初问题的更新,这些见解甚至让我自己确信,目前实际上没有内置配置可以返回拆分查询执行。

但是,MS 提供了代码示例,说明如何通过最少的代码更改来实现此目的(针对我们的用例!)here .

我们只是删除了对集合导航属性的 .Include(...) 调用(在我们的例子中是 1:n 关系,1:1 关系不受影响!)。获取项目后,我们只需使用以下命令进行另一个调用:

...
var myQueryable = this._context.Items.Where(**some filter**);
... // moar filters
var result = myQueryable.ToList();
...
var addInfos = myQueryable.Include(x => x.AddInfos).SelectMany(x => x.AddInfos).Select(x => new {x.ItemID, x}).ToList();

这会获取集合导航属性实体,并且 - 如果启用更改跟踪 - 自动填充 result 变量中各个项目的集合。

关于c# - Entity Framework Core 3.0 包含集合导航属性对性能的影响(笛卡尔爆炸),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59162778/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com