1

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

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(...)- Entity Framework 5 据说无法编译或缓存这些查询 - 因此每次都必须重新生成它们。这很糟糕,但我现在没有办法解决它。更糟糕的是,在生成查询时,EF 似乎阻塞了等待查询的其他线程。这真是太可怕了。
  2. 由于重复的主详细信息,包含大大增加了查询复杂性和返回的数据量。生成的 SQL 命令长达 2100 多行,执行计划直接来自地狱。

zones延迟加载的数据太多(除了通常很糟糕)而且我不知道有一种方法可以在我的变量上进行多次急切加载。

我是否需要进行多个查询,然后自己使用foreach循环和/或 LINQ 将数据压缩在一起?我确实需要将所有这些数据加载到内存中,否则我的计算将运行得非常糟糕。到目前为止,这实际上是我能做到的最快的。谢谢!

4

2 回答 2

1

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

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

于 2013-04-08T16:26:58.110 回答
0

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

是的。它可以帮助很多。许多集合会产生影响执行时间的大型连接。我遇到了同样的问题,并通过使用附加调用填充集合来解决。

于 2013-04-08T17:13:53.943 回答