EF优化所需的复杂LINQ查询



这是一个LINQ查询,用于从DB中检索具有实体框架的数据7。有几个.Where(x => x.CollectedMaterial.OrderByDescending(y => y.Repeats).First()。有没有办法优化此查询?是否需要这样做或EF优化它?

 var bs = await db.Building.Include(x => x.CollectedMaterial)
                    .Where(x => x.MaterialIDLocked == BuildingDataLockType.LockedByBuildingInfoSource)
                    .Where(x => x.CollectedMaterial.Count > 0)
                    .Where(
                        x => x.CollectedMaterial.OrderByDescending(y => y.Repeats).First().Repeats >= firstRepeatsCount)
                    .Where(x => x.CollectedMaterial.OrderByDescending(y => y.Repeats).First().MaterialID != x.MaterialID)
                    .ToListAsync();

afaik您不应使用多个在其中删除列表的多个列表,而应将条件放入单个子句中。

编辑:是的

提示:尝试滤除查询本身中的所有数据,不要通过获取不必要的数据来过滤内存对象,甚至可能使用不必要的字段,您可以使用投影操作仅选择所需的字段。

这里的答案也这样说,我通常会选择余额b/w可读性和性能,您应该尝试评估需要提高性能的程度,还可以尝试Visual Studio Profiler,它具有内存,CPU样本等。<<

如果您是在GET方法中编写该代码,则可以在DBSET上使用Asnotracking方法,这将改善性能,因为实体框架不会使用默认情况下创建的跟踪对象对其进行跟踪。

使用dbcontext对象上的database.log属性记录生成的sql查询,并通过更改代码查看哪个查询似乎很复杂,这将帮助您。

您可以登录控制台应用程序context.Database.Log = Console.WriteLine;

您可以登录任何其他应用程序以调试或跟踪为context.Database.Log = message => Trace.WriteLine(message);

由于您正在使用IQueryable,因此您可以根据需要将.Where()条件链链,您所创建的只是一个表达树,稍后将进行评估。

实际上从DB检索数据(如示例ToList()中)时,EF然后创建实际优化的SQL查询。

那么取决于..最好的做法是将SQL Profiler对您的DB运行并捕获并查看通过EF。

afaik,实体优化所有内容,直到实现实际的DB调用为止。在您的情况下,那是打电话给.ToListAsync的时候。

编辑:查看此评论,看来您应该合并所有查询。不过,如果可以的话,请考虑使用变量叛逆。

关于优化,您可能需要合并

.Where( x => x.CollectedMaterial.OrderByDescending(y => y.Repeats).First().Repeats >= firstRepeatsCount)
.Where( x => x.CollectedMaterial.OrderByDescending(y => y.Repeats).First().MaterialID != x.MaterialID)

to

.Where( x => {
    var firstRepeats = x.CollectedMaterial.OrderByDescending(y => y.Repeats).First().Repeats;
    return ( firstRepeats.Repeats >= firstRepeatsCount && 
             firstRepeats.MaterialID != x.MaterialID ) })

(未经测试)

最新更新