There is a heavy page in my site called HotelDetail
, that several things related to hotel will be load in this page. hotel, hotel's services,destinations of places to hotel,user's comments,hotel's room with their Services, prices and capacity.
All of this will be load in one time with below code, now I want to optimize this code, what's solution to optimize this for better performance and more readability ? is there a way to not load all of then in one time?
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));
}
}