public void TestCreateBookWriteTwiceDisconnectedBad() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); var oneBook = new Book { Title = "test" }; using var context = new EfCoreContext(options); context.Database.EnsureCreated(); context.Add(oneBook); context.SaveChanges(); context.ChangeTracker.Clear(); //ATTEMPT var state1 = context.Entry(oneBook).State; context.Add(oneBook); var state2 = context.Entry(oneBook).State; var ex = Assert.Throws <DbUpdateException>(() => context.SaveChanges()); //VERIFY ex.InnerException.Message.ShouldEqual("SQLite Error 19: 'UNIQUE constraint failed: Books.BookId'."); state1.ShouldEqual(EntityState.Detached); state2.ShouldEqual(EntityState.Added); }
public void TestExplicitLoadWithQueryBookOk() { //SETUP var options = this.ClassUniqueDatabaseSeeded4Books(); using (var context = new EfCoreContext(options)) { //ATTEMPT var book = context.Books.First(); //#A var numReviews = context.Entry(book) //#B .Collection(c => c.Reviews) //#B .Query().Count(); //#B var starRatings = context.Entry(book) //#C .Collection(c => c.Reviews) //#C .Query().Select(x => x.NumStars) //#C .ToList(); //#C /********************************************************* #A This reads in the first book on its own #B This executes a query to count how many reviews there are for this book #C This executes a query to get all the star ratings for the book * *******************************************************/ //VERIFY numReviews.ShouldEqual(0); starRatings.Count.ShouldEqual(0); } }
public void TestExplicitLoadWithQueryBookOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); } using (var context = new EfCoreContext(options)) { //ATTEMPT var firstBook = context.Books.First(); //#A var numReviews = context.Entry(firstBook) //#B .Collection(book => book.Reviews) //#B .Query().Count(); //#B var starRatings = context.Entry(firstBook) //#C .Collection(book => book.Reviews) //#C .Query().Select(review => review.NumStars) //#C .ToList(); //#C /********************************************************* #A This reads in the first book on its own #B This executes a query to count how many reviews there are for this book #C This executes a query to get all the star ratings for the book * *******************************************************/ //VERIFY numReviews.ShouldEqual(0); starRatings.Count.ShouldEqual(0); } }
public virtual void Delete(TEntity entityToDelete) { if (Context.Entry(entityToDelete).State == EntityState.Detached) { DbSet.Attach(entityToDelete); } DbSet.Remove(entityToDelete); }
private void MultipleSmall(EfCoreContext context, int id) { var book = context.Books.Single(x => x.BookId == id); context.Entry(book).Collection(c => c.AuthorsLink).Load(); foreach (var authorLink in book.AuthorsLink) { context.Entry(authorLink) .Reference(r => r.Author).Load(); } context.Entry(book).Collection(c => c.Reviews).Load(); context.Entry(book).Reference(r => r.Promotion).Load(); }
public bool Save(Plant plant) { if (plant.Id > 0) { _context.Entry(plant).State = EntityState.Modified; _context.Entry(plant).State = EntityState.Detached; } else { _context.Plants.Add(plant); } var result = _context.SaveChanges(); return(result > 0); }
private async Task MultipleSmallAsync(EfCoreContext context, int id) { var book = await context.Books.SingleAsync(x => x.BookId == id); await context.Entry(book).Collection(c => c.AuthorsLink).LoadAsync(); foreach (var authorLink in book.AuthorsLink) { await context.Entry(authorLink) .Reference(r => r.Author).LoadAsync(); } await context.Entry(book).Collection(c => c.Reviews).LoadAsync(); await context.Entry(book).Reference(r => r.Promotion).LoadAsync(); }
public void TestExplicitLoadBookOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); } using (var context = new EfCoreContext(options)) { //ATTEMPT var firstBook = context.Books.First(); //#A context.Entry(firstBook) .Collection(book => book.AuthorsLink).Load(); //#B foreach (var authorLink in firstBook.AuthorsLink) //#C { //#C context.Entry(authorLink) //#C .Reference(bookAuthor => //#C bookAuthor.Author).Load(); //#C } //#C context.Entry(firstBook) //#D .Collection(book => book.Reviews).Load(); //#D context.Entry(firstBook) //#E .Collection(book => book.Tags).Load(); //#E context.Entry(firstBook) //#F .Reference(book => book.Promotion).Load(); //#F /********************************************************* #A This reads in the first book on its own #B This explicitly loads the linking table, BookAuthor #C To load all the possible Authors it has to loop through all the BookAuthor entries and load each linked Author class #D This loads all the Reviews #E This loads the Tags #F This loads the optional PriceOffer class * *******************************************************/ //VERIFY firstBook.AuthorsLink.ShouldNotBeNull(); firstBook.AuthorsLink.First() .Author.ShouldNotBeNull(); firstBook.Reviews.ShouldNotBeNull(); } }
public bool Save(ChoreDto dto) { var entity = new Chore { Title = dto.Title, CreatedAt = dto.CreatedAt, PlantId = dto.PlantId, IntervalInDays = dto.IntervalInDays }; if (dto.Id != null) { entity.Id = (int)dto.Id; var completedChore = _context.CompletedChores.AsEnumerable()?.LastOrDefault(cc => cc.CreatedAt.Date == DateTime.Today && cc.ChoreId == dto.Id); if (dto.IsCompleted && completedChore == null) { _context.CompletedChores?.Add(new CompletedChore { Title = dto.Title, ChoreId = (int)dto.Id, CreatedAt = DateTime.Now, PlantId = dto.PlantId }); } else if (!dto.IsCompleted && completedChore != null) { _context.CompletedChores?.Remove(completedChore); } _context.Entry <Chore>(entity).State = EntityState.Modified; _context.Entry <Chore>(entity).State = EntityState.Detached; } else { _context.Chores.Add(entity); } var result = _context.SaveChanges(); return(result > 0); }
public void TestExplicitLoadBookOk() { //SETUP var options = this.ClassUniqueDatabaseSeeded4Books(); using (var context = new EfCoreContext(options)) { var logIt = new LogDbContext(context); //ATTEMPT var book = context.Books.First(); //#A context.Entry(book) .Collection(c => c.AuthorsLink).Load(); //#B foreach (var authorLink in book.AuthorsLink) //#C { //#C context.Entry(authorLink) //#C .Reference(r => r.Author).Load(); //#C } //#C context.Entry(book) //#D .Collection(c => c.Reviews).Load(); //#D context.Entry(book) //#E .Reference(r => r.Promotion).Load(); //#E /********************************************************* #A This reads in the first book on its own #B This explicitly loads the linking table, BookAuthor #C To load all the possible Authors it has to loop through all the BookAuthor entries and load each linked Author class #D This loads all the Reviews #E This loads the optional PriceOffer class * *******************************************************/ //VERIFY book.AuthorsLink.ShouldNotBeNull(); book.AuthorsLink.First() .Author.ShouldNotBeNull(); book.Reviews.ShouldNotBeNull(); foreach (var log in logIt.Logs) { _output.WriteLine(log); } } }
public void TestGetSingleOnEntityWhereOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var utData = context.SetupSingleDtoAndEntities <BookTitle>(); var service = new CrudServices(context, utData.ConfigAndMapper); //ATTEMPT var book = service.ReadSingle <Book>(x => x.BookId == 1); //VERIFY service.IsValid.ShouldBeTrue(service.GetAllErrors()); book.BookId.ShouldEqual(1); context.Entry(book).State.ShouldEqual(EntityState.Unchanged); } }
public void TestManyOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var utData = context.SetupSingleDtoAndEntities <BookTitle>(); var service = new CrudServices(context, utData.ConfigAndMapper); //ATTEMPT var books = service.ReadManyNoTracked <Book>(); //VERIFY service.IsValid.ShouldBeTrue(service.GetAllErrors()); books.Count().ShouldEqual(4); context.Entry(books.ToList().First()).State.ShouldEqual(EntityState.Detached); } }
public async Task TestGetSingleOnEntityOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var utData = context.SetupEntitiesDirect(); var service = new CrudServicesAsync(context, utData.ConfigAndMapper); //ATTEMPT var book = await service.ReadSingleAsync <Book>(1); //VERIFY service.IsValid.ShouldBeTrue(service.GetAllErrors()); book.BookId.ShouldEqual(1); context.Entry(book).State.ShouldEqual(EntityState.Unchanged); } }
public async Task TestManyOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var utData = context.SetupEntitiesDirect(); var service = new CrudServicesAsync(context, utData.ConfigAndMapper, new CreateNewDBContextHelper(() => new EfCoreContext(options))); //ATTEMPT var books = await service.ReadManyNoTracked <Book>().ToListAsync(); //VERIFY service.IsValid.ShouldBeTrue(service.GetAllErrors()); books.Count.ShouldEqual(4); context.Entry(books.ToList().First()).State.ShouldEqual(EntityState.Detached); } }
public void TestCreateBookWithExistingAuthor_CheckThreeStagesOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); } using (var context = new EfCoreContext(options)) { //STAGE1 var author = context.Authors.First(); var bookAuthor = new BookAuthor { Author = author }; var book = new Book { Title = "Test Book", AuthorsLink = new List <BookAuthor> { bookAuthor } }; //Read the states context.Entry(author).State.ShouldEqual(EntityState.Unchanged); context.Entry(bookAuthor).State.ShouldEqual(EntityState.Detached); context.Entry(book).State.ShouldEqual(EntityState.Detached); //These navigational links have not been set up book.AuthorsLink.Single().Book.ShouldBeNull(); author.BooksLink.ShouldBeNull(); //tracked PK/FK values not set context.Entry(book).Property(nameof(Book.BookId)).CurrentValue.ShouldEqual(0); context.Entry(bookAuthor).Property(nameof(BookAuthor.BookId)).CurrentValue.ShouldEqual(0); context.Entry(bookAuthor).Property(nameof(BookAuthor.AuthorId)).CurrentValue.ShouldEqual(0); //STAGE2 context.Add(book); //Read the states context.Entry(author).State.ShouldEqual(EntityState.Unchanged); context.Entry(bookAuthor).State.ShouldEqual(EntityState.Added); context.Entry(book).State.ShouldEqual(EntityState.Added); //Extra Navigational links filled in after call to Add book.AuthorsLink.Single().Book.ShouldEqual(book); author.BooksLink.Single().ShouldEqual(book.AuthorsLink.Single()); //Real PKs/FKs book.BookId.ShouldEqual(0); book.AuthorsLink.Single().BookId.ShouldEqual(0); book.AuthorsLink.Single().AuthorId.ShouldEqual(author.AuthorId); //tracked PK/FK values of new entities should be negative for Added classes, or actual PK if read in/Unchanged var tempBookId = (int)context.Entry(bookAuthor).Property(nameof(BookAuthor.BookId)).CurrentValue; (tempBookId < 0).ShouldBeTrue(); context.Entry(book).Property(nameof(Book.BookId)).CurrentValue.ShouldEqual(tempBookId); ((int)context.Entry(bookAuthor).Property(nameof(BookAuthor.AuthorId)).CurrentValue).ShouldEqual(author.AuthorId); //STAGE3 context.SaveChanges(); context.Entry(author).State.ShouldEqual(EntityState.Unchanged); context.Entry(bookAuthor).State.ShouldEqual(EntityState.Unchanged); context.Entry(book).State.ShouldEqual(EntityState.Unchanged); book.BookId.ShouldEqual(5); book.AuthorsLink.Single().BookId.ShouldEqual(book.BookId); book.AuthorsLink.Single().AuthorId.ShouldEqual(author.AuthorId); } }
public virtual void Edit(T entity) { _efCoreContext.Entry(entity).State = EntityState.Modified; _efCoreContext.SaveChanges(); }