The*_*hmu 11 c# performance entity-framework .net-core
将 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!
}
Run Code Online (Sandbox Code Playgroud)
和
public class AddInfo
{
[Key]
public int AddInfoID {get;set;}
public int? ItemID {get;set;}
public string SomePayload {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在项目检索期间,我们查询如下:
...
var myQueryable = this._context.Items.Include(i => i.AddInfos).Where(**some filter**);
... // moar filters
var result = myQueryable.ToList();
Run Code Online (Sandbox Code Playgroud)
直截了当,直到这一刻。
在EF 2.2,在获取两个单独的查询,一个用于可查询的结果Item,一个是AddInfo-水平。这些查询通常获取 10.000items和大约 250.000 AddInfos。
在EF核心3.0然而,正在生成一个单一的查询,左接合AddInfo到Item 上乍一看似乎是更好的选择。Item然而,我们需要获取所有 100 多个字段,这就是为什么投影到较小的类或匿名类型(添加对 .Select(...) 方法的调用)是不可行的。因此,结果集有太多的冗余(每个Item大约 25 次),以至于查询本身需要很长时间才能在可接受的时间内运行。
EF-Core 3.0 是否提供任何选项,使我们能够切换回旧的 EF Core 2.2 时代的查询行为,而无需对我们的数据模型进行大量更改?我们已经从应用程序其他部分的这种变化中获益,但在这个特定场景中却没有。
提前谢谢了!
更新
经过进一步调查,我发现,这个问题已经与微软不客气这里和开箱即用,似乎没有办法配置拆分查询执行。
根据我最初问题的更新,这些见解甚至让我自己确信,目前实际上没有内置配置可以返回拆分查询执行。
不过,MS在此处提供了有关如何通过最少的代码更改(针对我们的用例!)来执行此操作的代码示例。
我们只是删除了对集合导航属性的 .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();
Run Code Online (Sandbox Code Playgroud)
这将获取集合导航属性实体,并且 - 如果启用更改跟踪 - 自动填充变量中各个项目的集合result。
| 归档时间: |
|
| 查看次数: |
1299 次 |
| 最近记录: |