/// <summary> /// Find and hold the best available seats for a customer /// </summary> /// <param name="numSeats">count of seats to find and hold</param> /// <param name="customerEmail">unique identifier for the customer</param> /// <returns>a SeatHold object identifying the specific seats and related information</returns> public SeatHold findAndHoldSeats(int numSeats, string customerEmail) { SeatHold ret = null; DateTime dateTimeExpiration = DateTime.UtcNow.AddSeconds(-kSecondsHoldTimeout); using (var dbContext = new TicketSystemDbContext()) using (var transaction = dbContext.Database.BeginTransaction()) { var seats = (from seat in dbContext.Seats where seat.SeatClaimId == null || ( seat.SeatClaim.TimeStampReserved == null && seat.SeatClaim.TimeStampHeld != null && seat.SeatClaim.TimeStampHeld < dateTimeExpiration ) orderby seat.Rank descending select seat) .Take(numSeats) .ToList(); SeatClaim seatClaim = null; if (seats.Any()) { // cleanup seats so the existing invalid claim is removed seats.ForEach(seat => seat.SeatClaimId = null); // create new claim, in a 'hold' state as indicated by TimeStampHeld seatClaim = new SeatClaim { Email = customerEmail, TimeStampHeld = DateTime.UtcNow, TimeStampReserved = null, Seats = seats, HoldId = GenerateUniqueHoldId() }; } dbContext.SeatClaims.Add(seatClaim); seats.ForEach(seat => { seat.SeatClaim = seatClaim; }); dbContext.SaveChanges(); transaction.Commit(); ret = new SeatHold(numSeats, seatClaim, HoldTimeout); } return(ret); }
public SeatHold(int countRequested, SeatClaim seatClaim, TimeSpan holdTimeout) { SeatLocations = seatClaim.Seats .Select(seat => new SeatLocation { Row = seat.SeatRow, SeatNum = seat.SeatNum }) .ToList(); CountHeld = SeatLocations.Count; CountRequested = countRequested; HoldId = seatClaim.HoldId; HoldTimeout = holdTimeout; }