0

我的網站中有一個沉重的頁面,名爲HotelDetail,與酒店相關的幾件事將在此頁面加載。酒店,酒店的服務,酒店的目的地,用戶的評論,酒店的房間與他們的服務,價格和容量。 所有這些都將在一段時間內加載下面的代碼,現在我想優化這段代碼,有什麼解決方案來優化它以獲得更好的性能和更好的可讀性?有沒有辦法在一次不加載所有內容?如何優化我的實體框架查詢以獲得更好的性能和更高的可讀性

public PlaceViewModel GetPlaceDetail(string languageKey,string catKey , string placeKey, SearchViewModel searchOptions) 
     { 
       DateTime startDate = searchOptions.CheckIn.ToMiladiDateTime(); 
       DateTime endDate = searchOptions.CheckOut.ToMiladiDateTime(); 
       int nights = (int)endDate.Subtract(startDate).TotalDays; 
       placeViewModel.NightCount = nights; 
       var query = (from r in _unitOfWork.RoomServiceRepository.Get() 
          join 
           a in _unitOfWork.InventoryRepository.Get() 
           on r equals a.RoomService 
          where r.Room.Place.Id == place.Id && !r.SoftDelete && !r.Room.SoftDelete && 
            a.Date >= startDate && a.Date < endDate && (a.CertainAvailability + a.FloatAvailability) > 0 
          select new { a, MaxCapacity = r.Room.Capacity + r.ExtraCapacity, r.RoomId }); 

       placeViewModel.HasAvailability = query.ToList().Count != 0; 

       var grp = query.GroupBy(y => y.a.RoomServiceId) 
        .Select(z => new { 
         key = z.Key, 
         count = z.Count(), 
         minAvail = z.Min(ax => ax.a.CertainAvailability + ax.a.FloatAvailability), 
         minDate = z.Min(y => y.a.Date), 
         minPrice = z.Min(ax=>ax.a.Price), 
         price = z.Average(ax=>ax.a.Price) }); 

       var tmp = query.Where(x => grp.Any(q => 
        q.key == x.a.RoomServiceId && 
        q.count == nights && 
        q.minDate == x.a.Date)).ToList(); 
       foreach (var item in tmp) 
       { 
        var roomViewModel = placeViewModel.Rooms.FirstOrDefault(x => x.Id == item.RoomId); 
        var avail = new AvailabilityViewModel(item.a, item.MaxCapacity); 
        avail.Availability = grp.FirstOrDefault(x => x.key == item.a.RoomServiceId).minAvail; 
        var otherInfos = grp.SingleOrDefault(x => x.key == item.a.RoomServiceId); 
        avail.JabamaPrice = otherInfos.price; 
        avail.JabamaMinPriceInPeriod = otherInfos.minPrice; 
        roomViewModel.Availabilites.Add(avail); 
        if (maxDiscount == null || (maxDiscount != null &&(maxDiscount.BoardPrice - maxDiscount.JabamaPrice) < (avail.BoardPrice - avail.JabamaPrice))) 
         maxDiscount = avail; 
        if (minPrice == null || (minPrice != null && avail.JabamaPrice > 0 && minPrice.JabamaPrice > avail.JabamaPrice)) 
         minPrice = avail; 
       } 
       var discountQuery = tmp.Where(x => x.a.RoomService.ExtraCapacity == 0 && x.a.Date == minPrice.Date); 
       try 
       { 
        if (discountQuery.Any()) 
         maxDiscountOfMinPercentageDay = tmp != null && minPrice != null ? discountQuery.Max(x => (x.a.BoardPrice - x.a.Price)/x.a.BoardPrice * 100) : 0; 
        else 
         maxDiscountOfMinPercentageDay = 0; 

       } 
       catch (Exception) 
       { 
        maxDiscountOfMinPercentageDay = 0; 
       } 
       foreach (var roomVM in placeViewModel.Rooms) 
       { 
        if (roomVM.Availabilites.Count() == 0) 
         roomVM.Availabilites.Add(new AvailabilityViewModel(-1)); 
       } 
} 
+0

這絕對取決於你如何使用UI中的數據。你只應該得到你一目瞭然的東西。 – Massanu

+0

實際上它們都必須一目瞭然,但我也需要優化這些代碼,它變得複雜了, –

+0

您需要更加明確您正在尋找什麼類型的優化:性能,可讀性,可伸縮性等。 .. – Massanu

回答

0

我很不熟悉Linq,但我知道一些SQL的缺陷。我注意到的一件事是,你(以及其他許多人)使用.Count != 0來確定是否可能有匹配的記錄。在SQL中,這是一種非常低效的方法,因爲系統將有效地遍歷整個表來查找和計數符合先決條件的記錄。在這種情況下,我建議使用WHERE EXISTS()結構;我相信林克有類似的作品.Any()

這也是你在現實生活中所做的事情:當有人問你是否有冰箱裏剩下的奶酪時,你就不會開始計算你可以在那裏找到的所有類型的奶酪,而是在第一類你看到的奶酪並回答'是的';通過整個冰箱沒有附加價值,只會花費額外的時間。

PS:這大概也是如此的roomVM.Availabilites.Count() == 0這可能與反轉邏輯可以更好地處理...

免責聲明:這可能是因爲EntityFwk足夠聰明,在後臺優化這個給你。 .. 我不知道;我非常懷疑它,但就像我說的,我不是專家。我建議首先確定當前代碼的每個部分需要多長時間,然後優化最慢的代碼。有基線也給你一個更好的主意,如果你的變化有任何影響,無論是積極的還是消極的。