繁体   English   中英

EF优化需要复杂的LINQ查询吗?

[英]EF optimize complex LINQ query required?

这是一个LINQ查询,用于使用Entity Framework 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,您不应使用多个where子句来过滤列表,而应将条件放在单个where子句中。

编辑:是的,同时使用多个where子句似乎也很好

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

这里的答案也是如此,我通常会在黑白可读性和性能之间取得平衡,您应该尝试评估需要多少性能改进,还尝试使用Visual Studio Profiler,它具有内存,cpu采样等。

如果您使用get方法编写该代码,则可以在DbSet上使用AsNoTracking方法,这将提高性能,因为实体框架不会使用默认情况下创建的跟踪对象对其进行跟踪。

使用DbContext对象上的Database.Log属性记录生成的SQL查询,并通过更改代码来查看看起来复杂的查询,这将对您有所帮助。

您可以作为context.Database.Log = Console.WriteLine;登录Console App context.Database.Log = Console.WriteLine;

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

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

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

然后,这取决于..最好的办法是对数据库运行SQL事件探查器,并捕获并查看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)

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

(不过未经测试)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM