Ejemplo n.º 1
0
        public void Should_Create_New_Character_UsingDto()
        {
            // Arrange
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var existing = db.Characters.Find(1);
                existing.Should().BeNull();

                // Act
                var character = new CharacterDto
                {
                    Id       = 1,
                    Name     = "Steve",
                    Location = new CharacterLocationDto {
                        Name = "Earth"
                    },
                    Origin = new CharacterOriginDto {
                        Name = "Moon"
                    },
                    Episode = Array.Empty <string>()
                };
                var entity = mapper.Map <Character>(character);
                db.Characters.Add(entity);
                db.SaveChanges();
            }

            // Assert
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var found = db.Characters.Find(1);
                found.Should().NotBeNull();
                found.Name.Should().Be("Steve");
            }
        }
Ejemplo n.º 2
0
        protected EntityTestsBase()
        {
            // Use Sqlite in-memory database
            dbOptions = new DbContextOptionsBuilder <RickAndMortyContext>()
                        .UseSqlite(CreateInMemoryDatabase()).Options;

            using var db = new RickAndMortyContext(dbOptions);
            db.Database.EnsureCreated();
        }
Ejemplo n.º 3
0
        private static async Task CleanupDbAsync()
        {
            using var db = new RickAndMortyContext(dbOptions);
            db.Database.EnsureCreated();
            var existing = await db.Characters.CountAsync();

            Console.WriteLine($"Existing items {existing}");
            db.Database.EnsureDeleted();
            Console.WriteLine("DB deleted.");
            db.Database.EnsureCreated();
            Console.WriteLine("DB re-created.");
        }
Ejemplo n.º 4
0
        private static async Task FetchAndSaveWithTPL(PagedCharacters firstPage)
        {
            /* This is an experimental method and NOT in use.
             * This method links two DataFlow blocks.
             *  1. TransformBlock for fetching API data and pass to the next block
             *  2. AcitonBlock to save the fetched data.
             *
             *  The idea is that because API Fetch is much slower than the db insert,
             *  parallel execution of API fetch and db save can reduce some of db saving load.
             *
             *  But the result seems to show the gain from this approach is less than the overhead of
             *  having two TPL blocks being maintained.
             */

            var apiFetcher = new TransformBlock <int, PagedCharacters>(
                async pageNr =>
            {
                var result = await FetchCharacter(pageNr);
                return(result);
            }
                , new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism    = MaxParallel,
                SingleProducerConstrained = false
            });

            var saver = new ActionBlock <PagedCharacters>(pc =>
            {
                using var db = new RickAndMortyContext(dbOptions);
                db.BulkInsert(pc.Characters.ToArray());
                db.SaveChanges();
                Console.WriteLine($"Save finished. Page: {pc.CurrentPage}");
            }, new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = 1 //Do not allow concurrent writes
            });

            apiFetcher.LinkTo(saver, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            // Start by posting page numbers to the fetcher
            for (var pageNr = 2; pageNr <= firstPage.PageInfo.Pages; pageNr++)
            {
                await apiFetcher.SendAsync(pageNr);
            }

            apiFetcher.Complete();
            await saver.Completion;

            Console.WriteLine($"API fetch & save completed. Elapsed: {stopwatch.Elapsed}");
        }
Ejemplo n.º 5
0
 public void Should_Fail_New_Character_WithEmptyName()
 {
     // Arrange
     using (var db = new RickAndMortyContext(dbOptions))
     {
         // Act & Assert
         var character = new Character(id: 2, name: null);
         db.Characters.Add(character);
         var dbException  = Assert.Throws <DbUpdateException>(() => db.SaveChanges());
         var sqlException = dbException.InnerException as SqliteException;
         sqlException.SqliteErrorCode.Should().Be(19, "Inserting a null Name violates Not Null constraint.");
         //SQLite Error 19: 'NOT NULL constraint failed: Characters.Name'.
     }
 }
Ejemplo n.º 6
0
        private static void SaveItemsInConcurrentBag()
        {
            /*
             *    SQLite is file-based simple db and it locks the whole db when writing.
             *    Therefore, there is no gain at parallel writing.
             *    So, we write all the data at once.
             */

            var allCharacters = concurrentBag.SelectMany(n => n).ToArray();

            using var db = new RickAndMortyContext(dbOptions);
            // Use BulkInsert extension
            /* With SQLite, BulkInsert has no preformance gain since it does not support BulkCopy. */
            db.BulkInsert(allCharacters);
            db.SaveChanges();
            Console.WriteLine($"Data save finished. Elapsed: {stopwatch.Elapsed}");
        }
Ejemplo n.º 7
0
        public void Should_Create_New_Character_WithUrl()
        {
            // Arrange
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var existing = db.Characters.Find(3);
                existing.Should().BeNull();

                // Act
                var character = new Character(id: 3, name: "BlackPink", url: new Uri("http://www.google.com"));
                db.Characters.Add(character);
                db.SaveChanges();
            }

            // Assert
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var found = db.Characters.Find(3);
                found.Should().NotBeNull();
            }
        }
Ejemplo n.º 8
0
        public void Should_Create_New_Character()
        {
            // Arrange
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var existing = db.Characters.Find(1);
                existing.Should().BeNull();

                // Act
                var character = new Character(id: 1, name: "Mozart");
                db.Characters.Add(character);
                db.SaveChanges();
            }

            // Assert
            using (var db = new RickAndMortyContext(dbOptions))
            {
                var found = db.Characters.Find(1);
                found.Should().NotBeNull();
            }
        }
 public CharacterService(RickAndMortyContext context)
 {
     _context = context;
 }
Ejemplo n.º 10
0
 public CharactersController(RickAndMortyContext context, IMemoryCache memoryCache)
 {
     _context         = context;
     this.memoryCache = memoryCache;
 }
Ejemplo n.º 11
0
 private static void SavePage(PagedCharacters firstPage)
 {
     using var db = new RickAndMortyContext(dbOptions);
     db.BulkInsert(firstPage.Characters.ToArray());
     db.SaveChanges();
 }