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() 구조를 사용하는 것이 좋습니다. 나는 Linq이 비슷하게 작동하는 .Any()의 라인을 따라 뭔가를 가지고 있다고 믿습니다.

이것은 실제 생활에서하는 일이기도합니다. 누군가가 냉장고에 치즈가 남아 있는지 묻는다면, 거기에서 찾을 수있는 모든 종류의 치즈를 세지 않고 첫 번째 유형의 치즈를 멈추게 할 것입니다. 당신이보고 대답하는 치즈가 있습니다. 전체 냉장고를 통과하는 데 부가가치가 없기 때문에 여분의 시간이 소요됩니다.

PS : 이것은 아마도 ... 더 나은 반전 논리으로 처리 할 수 ​​roomVM.Availabilites.Count() == 0 마찬가지입니다

알림 : EntityFwk 백그라운드에서 당신을 위해 최적화 똑똑 것을이 될 수 있습니다. .. 나는 모른다. 나는 그것을 매우 의심하지만 내가 말했듯이 나는 전문가가 아니다. 처음에는 현재 코드의 각 부분이 얼마나 오래 걸리는지 파악한 다음 가장 느린 부분을 먼저 최적화하는 것이 좋습니다. 기준선을으로 설정하면 변경 사항에 긍정적 인 효과 또는 부정적 효과가 있는지 여부를 알 수 있습니다.