public async Task WriteBooksAsync(string filePath, int totalBooksNeeded, bool makeBookTitlesDistinct, CancellationToken cancellationToken) { _loadedBookData = JsonConvert.DeserializeObject <List <BookData> >(File.ReadAllText(filePath)) .ToImmutableList(); //Find out how many in db so we can pick up where we left off int numBooksInDb; using (var context = new SqlDbContext(_sqlOptions, null)) { numBooksInDb = await context.Books.IgnoreQueryFilters().CountAsync(); } var numWritten = 0; var numToWrite = totalBooksNeeded - numBooksInDb; while (numWritten < numToWrite) { if (cancellationToken.IsCancellationRequested) { return; } //noSql can be null. If so then it doesn't write to CosmosDb var noSqlBookUpdater = _noSqlOptions != null ? new NoSqlBookUpdater(new NoSqlDbContext(_noSqlOptions)) : null; using (var sqlDbContext = new SqlDbContext(_sqlOptions, noSqlBookUpdater)) { var authorsFinder = new AuthorFinder(sqlDbContext); var batchToAdd = Math.Min(_loadedBookData.Count, numToWrite - numWritten); var batch = GenerateBooks(batchToAdd, numBooksInDb, makeBookTitlesDistinct, authorsFinder).ToList(); sqlDbContext.AddRange(batch); await sqlDbContext.SaveChangesAsync(); numWritten += batch.Count; numBooksInDb += batch.Count; } } }
private IEnumerable <Book> GenerateBooks(int batchToAdd, int numBooksInDb, bool makeBookTitlesDistinct, AuthorFinder authorsFinder) { for (int i = numBooksInDb; i < numBooksInDb + batchToAdd; i++) { var sectionNum = (int)Math.Truncate(i / (double)NumBooksInSet); var authors = authorsFinder.GetAuthorsOfThisBook(_loadedBookData[i % _loadedBookData.Count].Authors).ToList(); var title = _loadedBookData[i % _loadedBookData.Count].Title; if (sectionNum > 0 && makeBookTitlesDistinct) { title += $" (copy {sectionNum})"; } var book = Book.CreateBook(title, $"Book{i:D4} Description", _loadedBookData[i % _loadedBookData.Count].PublishDate.AddDays(sectionNum), "Manning", (i + 1), null, authors).Result; //setup the author cache value for the SQL Events version book.AuthorsOrdered = string.Join(", ", authors.Select(x => x.Name)); for (int j = 0; j < i % 12; j++) { book.AddReview((Math.Abs(3 - j) % 4) + 2, null, j.ToString()); } if (i % 7 == 0) { book.AddPromotion(book.ActualPrice * 0.5m, "today only - 50% off! "); } if (book.Reviews.Any()) { //setup the reviews cache values for the SQL Events version book.ReviewsCount = book.Reviews.Count(); book.ReviewsAverageVotes = book.Reviews.Sum(x => x.NumStars) / (double)book.ReviewsCount; } yield return(book); } }