public IEnumerable<Exchange> GetRange(DateTime startDate, DateTime endDate, string targetCurrencyCode) { var exchangesInRange = this.dbSet .Where( e => startDate <= e.Date && e.Date <= endDate ) .ToList(); var targetExchanges = exchangesInRange .Where( e => e.CurrencyCode == targetCurrencyCode ) .ToList(); var numberOfDaysInRange = (endDate - startDate).Days + 1; // Inclusive. if (targetExchanges.Count == numberOfDaysInRange) return targetExchanges; var availableDatesInRange = exchangesInRange.Select(ex => ex.Date).Distinct(); var availableTargetDates = targetExchanges.Select(ex => ex.Date); var rangeCount = availableDatesInRange.Count(); var targetCount = availableTargetDates.Count(); if (rangeCount != targetCount) { Trace.WriteLine("For the range given there are "+rangeCount+" dates in the db, "+targetCount+" of them are for "+targetCurrencyCode+"."); var resEx = new ExchangeResource.TryRequestingOtherDatesOrCurrency( "Rates for "+targetCurrencyCode+" are not available for some of the dates requested." ); var absentTargetDates = availableDatesInRange.Except(availableTargetDates); resEx.AddFailedDates(absentTargetDates); throw resEx; } Trace.WriteLine( String.Format("Found rates for {0} out of {1} days in the DB. Let's retrieve the rest!", targetExchanges.Count, numberOfDaysInRange) ); var currentDate = startDate; var availableDates = targetExchanges.Select(e => e.Date).ToDictionary(d => d); var datesToRetrieve = new List<DateTime>(numberOfDaysInRange - targetExchanges.Count); while (currentDate <= endDate) // Inclusive. { if (!availableDates.ContainsKey(currentDate)) { datesToRetrieve.Add(currentDate); } currentDate = currentDate.AddDays(1); } Trace.WriteLine("We have " + datesToRetrieve.Count + " dates to retrieve."); IEnumerable<Exchange> retrievedExchanges; try { Trace.WriteLine("Call to exchange external resource."); retrievedExchanges = DataAccessLayer.ExchangeResources .External .DefaultExternalResource .RetrieveAndPopulateExchanges( datesToRetrieve, targetCurrencyCode, this.dbSet // TODO: test that if dbSet is populated then it is saved to the db on SaveChanges. ); } finally { this.exchangeContext.SaveChanges(); } return targetExchanges.Concat(retrievedExchanges.Where(ex => ex.CurrencyCode == targetCurrencyCode)); }
public IEnumerable <Exchange> GetRange(DateTime startDate, DateTime endDate, string targetCurrencyCode) { var exchangesInRange = this.dbSet .Where( e => startDate <= e.Date && e.Date <= endDate ) .ToList(); var targetExchanges = exchangesInRange .Where( e => e.CurrencyCode == targetCurrencyCode ) .ToList(); var numberOfDaysInRange = (endDate - startDate).Days + 1; // Inclusive. if (targetExchanges.Count == numberOfDaysInRange) { return(targetExchanges); } var availableDatesInRange = exchangesInRange.Select(ex => ex.Date).Distinct(); var availableTargetDates = targetExchanges.Select(ex => ex.Date); var rangeCount = availableDatesInRange.Count(); var targetCount = availableTargetDates.Count(); if (rangeCount != targetCount) { Trace.WriteLine("For the range given there are " + rangeCount + " dates in the db, " + targetCount + " of them are for " + targetCurrencyCode + "."); var resEx = new ExchangeResource.TryRequestingOtherDatesOrCurrency( "Rates for " + targetCurrencyCode + " are not available for some of the dates requested." ); var absentTargetDates = availableDatesInRange.Except(availableTargetDates); resEx.AddFailedDates(absentTargetDates); throw resEx; } Trace.WriteLine( String.Format("Found rates for {0} out of {1} days in the DB. Let's retrieve the rest!", targetExchanges.Count, numberOfDaysInRange) ); var currentDate = startDate; var availableDates = targetExchanges.Select(e => e.Date).ToDictionary(d => d); var datesToRetrieve = new List <DateTime>(numberOfDaysInRange - targetExchanges.Count); while (currentDate <= endDate) // Inclusive. { if (!availableDates.ContainsKey(currentDate)) { datesToRetrieve.Add(currentDate); } currentDate = currentDate.AddDays(1); } Trace.WriteLine("We have " + datesToRetrieve.Count + " dates to retrieve."); IEnumerable <Exchange> retrievedExchanges; try { Trace.WriteLine("Call to exchange external resource."); retrievedExchanges = DataAccessLayer.ExchangeResources .External .DefaultExternalResource .RetrieveAndPopulateExchanges( datesToRetrieve, targetCurrencyCode, this.dbSet // TODO: test that if dbSet is populated then it is saved to the db on SaveChanges. ); } finally { this.exchangeContext.SaveChanges(); } return(targetExchanges.Concat(retrievedExchanges.Where(ex => ex.CurrencyCode == targetCurrencyCode))); }