简化实体框架中复杂的包括连接

本文关键字:包括 连接 复杂 实体 框架 | 更新日期: 2023-09-27 18:08:09

现在我有一个非常复杂的查询,我需要加载大量数据进行处理。数据嵌套非常深…

public List<agZone> agZone_GetZonesWithProjectionInformation(IEnumerable<int> ids, bool includeHidden)
{
    var zones = this.BaseDB.agZones.Where(x => (includeHidden || includeHidden == x.agField.Hidden)
                                && x.agField.WeatherSourceID.HasValue
                                && x.agField.WeatherProjectionID.HasValue
                                && x.agField.SeedID.HasValue
                                && ids.Contains(x.ZoneID))
                        .Include(x => x.agField)
                        .Include(x => x.agField.agSeed)
                        .Include(x => x.agField.agSeed.agSeedCompany)
                        .Include(x => x.agField.agSeed.agSeedConfigs)
                        .Include(x => x.agField.agSeed.agSeedGrowthStages)
                        .Include(x => x.agField.agSeed.agSeedGrowthStages.Select(y => y.agGrowthStage))
                        .Include(x => x.agField.agFieldGrowthStages)
                        .Include(x => x.agField.agFarm)
                        .Include(x => x.agField.agFarm.agGrower)
                        .Include(x => x.agField.agFarm.agGrower.agUsers)
                        .Include(x => x.agZoneNitrogenApplications)
                        .Include(x => x.agZoneWaterApplications)
                        .Include(x => x.agSoilSymbol)
                        .Include(x => x.agSoilSymbol.agSoilConfigs)
                        .AsNoTracking();
    return zones.ToList();
}

到目前为止,我知道这里发生了两件不好的事情:

  1. 查询使用.Contains(...) -实体框架5据说不能编译或缓存这些查询-所以他们必须每次重新生成。很糟糕,但是我现在没有办法解决它。更糟糕的是,当查询生成时,EF似乎阻塞了等待查询的其他线程。这真是太可怕了。
  2. 包含极大地增加了查询的复杂性和返回的数据量,因为重复的主详细信息。生成的SQL命令有2100多行,执行计划简直一团糟。

有太多的数据要延迟加载(除了这通常是可怕的),我不知道有一种方法可以在我的zones变量上进行多次急切加载。

我是否需要进行多个查询,然后将数据与foreach循环和/或LINQ一起压扁?我确实需要将所有这些数据加载到内存中,否则我的计算将运行得非常糟糕。到目前为止,这是我最快的速度了。谢谢!

简化实体框架中复杂的包括连接

另一种方法可能是在数据库上创建一个SQL视图,并对其进行简单的EF映射。仅这一点就可以大大降低性能影响。

您甚至可以考虑在单独的表或其自己的数据存储中创建一个非规范化投影。可以在相关数据被修改时动态地执行,也可以作为批处理作业不时地执行,这取决于您需要这些数据的频率和及时程度。CQRS可能很适合这个特定的问题。

我是否需要进行多个查询,然后用foreach循环和/或LINQ将数据压扁在一起?

是的。这可能会有很大帮助。许多集合会产生影响执行时间的大型连接。我也有同样的问题,它是通过填充集合与额外的调用来解决的。