我有一个庞大的LINQ查询,它获取如下所示的信息:

c# - Linq Count内部选择,嵌套,可最大程度地减少立即执行数据库依赖项-LMLPHP

换句话说,第一级类别拥有第二级类别,第三级类别拥有。对于每个类别,我们检索其包含的列表数量。

这是查询:

categories = categoryRepository
           .Categories
           .Where(x => x.ParentID == null)
           .Select(x => new CategoryBrowseIndexViewModel
           {
               CategoryID = x.CategoryID,
               FriendlyName = x.FriendlyName,
               RoutingName = x.RoutingName,
               ListingCount = listingRepository
                              .Listings
                              .Where(y => y.SelectedCategoryOneID == x.CategoryID
                                       && y.Lister.Status != Subscription.StatusEnum.Cancelled.ToString())
                              .Count(),

               BrowseCategoriesLevelTwoViewModels = categoryRepository
                    .Categories
                    .Where(a => a.ParentID == x.CategoryID)
                    .Select(a => new BrowseCategoriesLevelTwoViewModel
                    {
                        CategoryID = a.CategoryID,
                        FriendlyName = a.FriendlyName,
                        RoutingName = a.RoutingName,
                        ParentRoutingName = x.RoutingName,
                        ListingCount = listingRepository
                                       .Listings
                                       .Where(n => n.SelectedCategoryTwoID == a.CategoryID
                                                && n.Lister.Status != Subscription.StatusEnum.Cancelled.ToString())
                                       .Count(),

                        BrowseCategoriesLevelThreeViewModels = categoryRepository
                                         .Categories
                                         .Where(b => b.ParentID == a.CategoryID)
                                         .Select(b => new BrowseCategoriesLevelThreeViewModel
                                         {
                                             CategoryID = b.CategoryID,
                                             FriendlyName = b.FriendlyName,
                                             RoutingName = b.RoutingName,
                                             ParentRoutingName = a.RoutingName,
                                             ParentParentID = x.CategoryID,
                                             ParentParentRoutingName = x.RoutingName,
                                             ListingCount = listingRepository
                                                            .Listings
                                                            .Where(n => n.SelectedCategoryThreeID == b.CategoryID
                                                                     && n.Lister.Status != Subscription.StatusEnum.Cancelled.ToString())
                                                            .Count()
                                         })
                                         .Distinct()
                                         .OrderBy(b => b.FriendlyName)
                                         .ToList()
                    })
                    .Distinct()
                    .OrderBy(a => a.FriendlyName)
                    .ToList()
           })
           .Distinct()
           .OrderBy(x => x.FriendlyName == jobVacanciesFriendlyName)
           .ThenBy(x => x.FriendlyName == servicesLabourHireFriendlyName)
           .ThenBy(x => x.FriendlyName == goodsEquipmentFriendlyName)
           .ToList();


这在我的开发机上已经足够快了,但是a!部署到Azure的速度非常慢。原因似乎是此查询正在对数据库进行数百次依赖关系调用,我很确定是因为立即执行Count语句。尽管应用程序和数据库位于同一个数据中心中,但调用的累加方式与我的开发机上不同(〜40s vs

最佳答案

这是我对大量查询的建议。


不要在内部查询中使用ToList()
不要在内部查询中使用Count()


尝试不通过once操作就检索所有IEnumerable数据。换句话说,以IQueryable模式获取数据。将其加载到应用程序的内存中后,您可以根据需要创建数据模型。此过程将为您的应用程序带来巨大的性能提升。请尝试并告知我们。

更新:关于Count()

如果列表中有很多列,只需使用Count()而不用projection来获取1列,然后可以在count()列表中获取IEnumerable,换句话说,获取应用后的内存从db

关于c# - Linq Count内部选择,嵌套,可最大程度地减少立即执行数据库依赖项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39657841/

10-15 18:15
查看更多