public void CanInsertSamuraiWithQuotes() { var samuraiGraph = new Samurai { Name = "Kyūzō", Quotes = new List <Quote> { new Quote { Text = "Watch out for my sharp sword" }, new Quote { Text = "I told you to watch out for my sharp sword! Oh well!" } } }; var builder = new DbContextOptionsBuilder(); builder.UseInMemoryDatabase("SamuraiWithQuotes"); using (var context = new SamuraiConsoleContext(builder.Options)) { var bizlogic = new BusinessDataLogic(context); var result = bizlogic.InsertNewSamurai(samuraiGraph); } using (var context2 = new SamuraiConsoleContext(builder.Options)) { var samurai = context2.Samurais.Include(s => s.Quotes).FirstOrDefaultAsync().Result; Assert.AreEqual(2, samurai.Quotes.Count); // Check if the InMemory database is shared across tests (it is): var samurais = context2.Samurais.ToList(); } }
private static void AddingQuoteToExistingSamuraiWhileNotTracked(int samuraiId) { var samurai = context.Samurais.Find(samuraiId); samurai.Quotes.Add(new Quote { Text = "Now that I saved you, will you feed me dinner?" }); using (var newContext = new SamuraiConsoleContext()) { // Use 'Update' to start tracking the graph. // As child's key value is not set state will automatically be set as 'added' // Child's FK valueto parent, 'samuraiId', is set to parent\s key. // Using Update // Update will also make a db call to update the samurai, although no changes has been made // newContext.Samurais.Update(samurai); // Using Attach // Use 'attach' instead when adding related objects, not editing the parent itself. // This sets it state to 'unmodified' but still recognized // the missing key and fk in the quote object. // ...or just set the fk on the Samurai (se next method) newContext.Samurais.Attach(samurai); newContext.SaveChanges(); } }
public BusinessDataLogic() { _context = new SamuraiConsoleContext(); // Issue: When creating the 'SamuraiTestData' DB from the SamuraiConsoleContext the Functions // and Stored Procedures are not created. // Create and rename the 'SamuraiAppData' db created by the SamuraiContext. // Issue: _context.Database.EnsureCreated(); }
public void AddMultipleSamuraisReturnsCorrectNumberOfInsertedRows() { var builder = new DbContextOptionsBuilder(); builder.UseInMemoryDatabase("AddMultipleSamurais"); using (var context = new SamuraiConsoleContext(builder.Options)) { var bizLogic = new BusinessDataLogic(context); var nameList = new string[] { "Kikuchiyo", "Kyuzo", "Rikchi" }; var result = bizLogic.AddMultipleSamurais(nameList); Assert.AreEqual(nameList.Count(), result); } }
private static void QueryAndUpdateBattle_Disconnected() { // AsNoTracking returns a query, not a DbSet. DbSet methods like 'Find' won't be available. var battle = context.Battles.AsNoTracking().FirstOrDefault(); battle.EndDate = new DateTime(1560, 06, 30); using (var newContextInstance = new SamuraiConsoleContext()) { // Update: Context will start tracking the object and mark its state as 'modified' // Teis: I think 'Update' is only used in disconnected scenarios newContextInstance.Battles.Update(battle); newContextInstance.SaveChanges(); } }
private static void ModifyingRelatedDataWhenNotTracked() { var samurai = context.Samurais.Include(s => s.Quotes).FirstOrDefault(s => s.Id == 19); var quote = samurai.Quotes[0]; quote.Text = "Did you hear that again?"; using (var newContext = new SamuraiConsoleContext()) { // Don't use this. It will update the parent samurai and all its quotes. // Don't use: newContext.Quotes.Update(quote); // ...use this instead. Will only modify the quote in the database. newContext.Entry(quote).State = EntityState.Modified; newContext.SaveChanges(); } }
private static void AddingQuoteToExistingSamuraiWhileNotTracked_Easy(int samuraiId) { var quote = new Quote { Text = "Now that I saved you, will you feed me dinner?", // Somewhat 'unclean', but makes everything easier. SamuraiId = samuraiId }; using (var newContext = new SamuraiConsoleContext()) { // ...or just set the fk on the Samurai (se next method) newContext.Quotes.Add(quote); newContext.SaveChanges(); } }
public void CanInsertSingeSamurai() { var builder = new DbContextOptionsBuilder(); builder.UseInMemoryDatabase("InsertSingeSamurai"); using (var context = new SamuraiConsoleContext(builder.Options)) { var bizLogic = new BusinessDataLogic(context); bizLogic.InsertNewSamurai(new Samurai()); } using (var context2 = new SamuraiConsoleContext(builder.Options)) { Assert.AreEqual(1, context2.Samurais.Count()); } }
public void CanInsertSamuraiIntoDatabase() { using (var context = new SamuraiConsoleContext()) { // context.Database.EnsureDeleted(); // Takes long time context.Database.EnsureCreated(); var samurai = new Samurai(); // Properties are non-nullable needs to be populated in advance, eg. the 'Name' field. context.Samurais.Add(samurai); Debug.WriteLine($"Before save: {samurai.Id}"); context.SaveChanges(); Debug.WriteLine($"After save: {samurai.Id}"); Assert.AreNotEqual(0, samurai.Id); } }
private static void AddNewHorseToDisconnectedSamuraiObject() { var samurai = context.Samurais.AsNoTracking().FirstOrDefault(s => s.Id == 18); samurai.Horse = new Horse { Name = "Mr. Ed" }; samurai.Name += " Draiby"; using (var newContext = new SamuraiConsoleContext()) { // Using the 'Attach' method, there os only one db call inserting into the Horses table. // Teis: What if the Samurai object HAS beed changed? Will it then be updated as well? // Teis: Answer: NO // Teis: Probably no if samurais had foreign horse keys as well. // EF Core sees that the samurai already has an id and will mark it as unchanged. // but because the horse doesn't have an id, so its state will be set to 'added'. newContext.Attach(samurai); newContext.SaveChanges(); } }
public void CanInsertSamuraiIntoDatabase() { var builder = new DbContextOptionsBuilder(); // Passing a name so the db can be used elsewhere using 'UseInMemoryDatabase' again. builder.UseInMemoryDatabase("CanInsertSamurai"); using (var context = new SamuraiConsoleContext(builder.Options)) { // context.Database.EnsureDeleted(); // Takes long time // 'EnsureCreated' can be used to seed the database with the EF Core migrations // context.Database.EnsureCreated(); var samurai = new Samurai(); context.Samurais.Add(samurai); // Properties are non-nullable needs to be populated in advance, eg. the 'Name' field. // Because the InMemory database is used, the samurai already gets its id when using 'Add', not 'SaveChanges' // 'SaveChanges' only make sense when testing with a real databse. // Use 'Samurais.Count' to check if added or: Assert.AreEqual(EntityState.Added, context.Entry(samurai).State); } }
public void CanGetSamuraiWithQuotes() { int samuraiId; var builder = new DbContextOptionsBuilder(); // Teis question: won't the reuse of the InMemory db name 'SamuraiWithQuotes' // interfere with the previous test using the same name? // Answer: The database is shared across tests but they don't interefere with each other (bad practice though) builder.UseInMemoryDatabase("SamuraiWithQuotes"); using (var seedContext = new SamuraiConsoleContext(builder.Options)) { var samuraiGraph = new Samurai { Name = "Kyūzō", Quotes = new List <Quote> { new Quote { Text = "Watch out for my sharp sword" }, new Quote { Text = "I told you to watch out for my sharp sword! Oh well!" } } }; seedContext.Samurais.Add(samuraiGraph); seedContext.SaveChanges(); samuraiId = samuraiGraph.Id; } using (var context = new SamuraiConsoleContext(builder.Options)) { // Check if the InMemory database is shared across tests (it is): var samurais = context.Samurais.ToList(); var bizlogic = new BusinessDataLogic(context); var result = bizlogic.GetSamuraiWithQuotes(samuraiId); Assert.AreEqual(2, result.Quotes.Count); } }
public BusinessDataLogic(SamuraiConsoleContext context) { this._context = context; }