private static void ModifyingRelatedDataWhenTracked() { var samurai = context.Samurais.Include(s => s.Quotes).FirstOrDefault(s => s.Id == 19); samurai.Quotes[0].Text = "Did you hear that?"; context.Quotes.Remove(samurai.Quotes[2]); context.SaveChanges(); }
private static void RemoveJoinBetweenSamuraiAndBattleSimple() { var join = new SamuraiBattle { BattleId = 1, SamuraiId = 11 }; // Begin tracking and set state as deleted (only the delete call is performed on the database). context.Remove(join); context.SaveChanges(); }
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 int AddMultipleSamurais(string[] nameList) { var samuraiList = new List <Samurai>(); foreach (var name in nameList) { samuraiList.Add(new Samurai { Name = name }); } _context.Samurais.AddRange(samuraiList); var dbResult = _context.SaveChanges(); return(dbResult); }
private static void AddSamurai() { var samurai = new Samurai { Name = "Julie" }; context.Samurais.Add(samurai); context.SaveChanges(); }
private static void ReplaceAHorse() { // Horse already trached in memory: var samurai = context.Samurais.Include(s => s.Horse).FirstOrDefault(s => s.Id == 18); // Already has a horse /* * Will throw, as the horse object needs to be in memory. EF will just send an insert to the db: * samurai = context.Samurais.Find(23); // Already has a horse * samurai.Horse = new Horse { Name = "Trigger" }; */ // For 'horse trading' you can also set the horse's SamuraiId to the new samurai owner. // The db call will first delete the old horse and the insert the new horse, // because there can not be a horse without a samurai. context.SaveChanges(); }
private static void InsertBattle() { context.Battles.Add(new Battle { Name = "Battle of Okehazma", StartDate = new DateTime(1560, 05, 01), EndDate = new DateTime(1560, 06, 15) }); context.SaveChanges(); }
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 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 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); } }