// ************** // UPDATE BUTTON // ************** private void update_Click(object sender, EventArgs e) { if (mskTxtAnimal.Text != "" && cmbHabitat.SelectedIndex != 0 && cmbSpecies.SelectedIndex != 0 && cmbDiet.SelectedIndex != 0 && mskTxtWeight.Text != "" && SelectedAnimalID > 0) { // at least one field has been changed before pressin SAVE // Need to check: // - if data is ALREADY in DB or NEW records // data is assumed the same if all data the same as existing using (var db = new ZooContext()) { // Case with UPDATE Existing record var newAnimal = new Animal(); var newOrigin = new Origin(); var tmpOrigin = new Origin(); if (cmbOrigin.SelectedIndex == 0 || cmbOrigin.Text == "") // All or empty { MessageBox.Show("Please choose an Origin country/continent."); // Need to jump all the code below! } else //if (cmbOrigin.SelectedIndex == -1) // A new country/continent has been inserted { tmpOrigin = (cmbOrigin.SelectedIndex == -1) ? db.Origins.Include("Animals").FirstOrDefault(c => c.Name == cmbOrigin.Text) : db.Origins.Include("Animals").FirstOrDefault(c => c.Name == cmbOrigin.SelectedItem.ToString()); if (tmpOrigin == null) { newOrigin.Name = cmbOrigin.Text; newOrigin.Animals.Add(newAnimal); } else { // newAnimal.Origin.OriginId = tmpOrigin.OriginId; // Search the ID of the existing country/continent and save it in "newAnimal" newAnimal.Origin = tmpOrigin; // db.Origins.Where(c => c.Name == cmbOrigin.SelectedItem.ToString()).Select(c => c.OriginId).SingleOrDefault(); } //Check against DB var temp = Convert.ToDouble(mskTxtWeight.Text); var animalReadyExist = db.Animals.Where(c => c.Name == mskTxtAnimal.Text && c.Weight == temp && c.Habitat.Name == cmbHabitat.SelectedItem.ToString() && c.Species.Name == cmbSpecies.SelectedItem.ToString() && c.Origin.Name == newAnimal.Origin.Name && c.Diet.Name == cmbDiet.SelectedItem.ToString()).Any(); // Initializing some variables var currentAnimaltoUpdate = service.GetSelectedAnimal(db, SelectedAnimalID); var childParentsLinks = service.GetParentsLinks(db, currentAnimaltoUpdate.Name); string parentInCombo1 = cmbParent1.SelectedItem?.ToString(); string parentInCombo2 = cmbParent2.SelectedItem?.ToString(); int childTotParents = childParentsLinks.Count(); // there might be links to parents which ave ParentID = null! I need to check these fields in the update! bool skipUpdate = false; var childChildrenLinks = currentAnimaltoUpdate.IsParentOf.ToList(); // Check that the current Animal´s parents are NOT the same as his/her own children // Only 1-level is verified. Need a method for analysis av the full tree. switch (childChildrenLinks.Count()) { case 0: // current animal has NO children break; case 1: if (childChildrenLinks[0].Child.Name == parentInCombo1 || (childChildrenLinks[0].Child.Name == parentInCombo2)) { MessageBox.Show("This Animal cannot have Parent(s) with same Name as his own children"); skipUpdate = true; } break; case 2: if (childChildrenLinks[0].Child.Name == parentInCombo1 || childChildrenLinks[0].Child.Name == parentInCombo2 || childChildrenLinks[1].Child.Name == parentInCombo1 || childChildrenLinks[1].Child.Name == parentInCombo2) { MessageBox.Show("This Animal cannot have Parent(s) with same Name as his own children"); skipUpdate = true; } break; } if (!skipUpdate) { bool addParent1 = false; bool addParent2 = false; bool remParent1 = false; bool remParent2 = false; bool sameName = false; if (parentInCombo1 != "All" && parentInCombo2 != "All" && parentInCombo1 == parentInCombo2) { MessageBox.Show("Select two different parents or set to 'All' for no parents"); sameName = true; } else if (parentInCombo1 != "All" && parentInCombo1 == currentAnimaltoUpdate.Name) { // Parent1 name is SAME as Child --> update not possible MessageBox.Show("Parent cannot have the same Name as the Animal"); sameName = true; } else if (parentInCombo2 != "All" && parentInCombo2 == currentAnimaltoUpdate.Name) { // Parent1 name is SAME as Child --> update not possible MessageBox.Show("Parent cannot have the same Name as the Animal"); sameName = true; } else { switch (childTotParents) { case 0: // no parents if (parentInCombo1 != "All") { addParent1 = true; } if (parentInCombo2 != "All") { addParent2 = true; } break; case 1: // 1 parent if (parentInCombo1 != "All") { if (parentInCombo1 == childParentsLinks.ToList()[0].Parent.Name) { addParent1 = false; } else { addParent1 = true; } } else { remParent1 = true; } if (parentInCombo2 != "All") { if (parentInCombo2 == childParentsLinks.ToList()[0].Parent.Name) { addParent2 = false; } else { addParent2 = true; } } break; case 2: // 2 parents if (parentInCombo1 != "All") { if (parentInCombo1 == childParentsLinks.ToList()[0].Parent.Name) { addParent1 = false; } else if (parentInCombo1 == childParentsLinks.ToList()[1].Parent.Name) { addParent1 = false; } else { addParent1 = true; } } else { remParent1 = true; } if (parentInCombo2 != "All") { if (parentInCombo2 == childParentsLinks.ToList()[0].Parent.Name) { addParent2 = false; } else if (parentInCombo2 == childParentsLinks.ToList()[1].Parent.Name) { addParent2 = false; } else { addParent2 = true; } } else { remParent2 = true; } break; } } // animalReadyExist = (!addParent1 && !addParent2) || (!remParent1 && !remParent2); if (animalReadyExist && !addParent1 && !addParent2 && !remParent1 && !remParent2) { if (!sameName) { MessageBox.Show("Animal is already registered"); } } else { // Animal IS NOT in DB // OK Proceed with MODIFING One existing Animal detected by SelectedAnimalID Globl VAriable // save all data in an new Animal() istance newAnimal.Name = mskTxtAnimal.Text; if (mskTxtWeight.Text == "") { newAnimal.Weight = 0.0; } else { newAnimal.Weight = Convert.ToDouble(mskTxtWeight.Text); } newAnimal.HabitatId = db.Habitats.Where(c => c.Name == cmbHabitat.SelectedItem.ToString()).Select(c => c.HabitatId).SingleOrDefault(); newAnimal.SpeciesId = db.Species.Where(c => c.Name == cmbSpecies.SelectedItem.ToString()).Select(c => c.SpeciesId).SingleOrDefault(); newAnimal.OriginId = newAnimal.Origin.OriginId; // db.Origins.Where(c => c.Name == newAnimal.Origin.Name).Select(c => c.OriginId).SingleOrDefault(); newAnimal.DietId = db.Diets.Where(c => c.Name == cmbDiet.SelectedItem.ToString()).Select(c => c.DietId).SingleOrDefault(); db.SaveChanges(); // I need this because when i create a new Origin, I have NO id assigned to the class Origin. // Updating... currentAnimaltoUpdate.Name = newAnimal.Name; currentAnimaltoUpdate.Weight = newAnimal.Weight; currentAnimaltoUpdate.HabitatId = newAnimal.HabitatId; currentAnimaltoUpdate.SpeciesId = newAnimal.SpeciesId; currentAnimaltoUpdate.OriginId = newAnimal.OriginId; currentAnimaltoUpdate.DietId = newAnimal.DietId; // Since animalReadyExist = false, then it is more efficient to REMOVE the links to the Parent(s) of the currentAnimaltoUpdate // and ADD the names in the Comboboxes if any. //foreach (var linkToParent in childParentsLinks) var myanimal = new Animal(); var relation = new ChildParent(); while (currentAnimaltoUpdate.IsChildOf.Count() != 0) { myanimal = db.Animals.Include("IsChildOf").Where(c => c.AnimalId == SelectedAnimalID).FirstOrDefault(); relation = myanimal.IsChildOf.FirstOrDefault(); myanimal.IsChildOf.Remove(relation); db.SaveChanges(); } // I need to search in the db the Entities mapped to the parent 1/2 comboboxes and from there Add this new Animal // as Child if (service.UpdateChildParentsLinks(db, currentAnimaltoUpdate, parentInCombo1)) { // test message to be removed MessageBox.Show("Parent 1 has been updated!"); } // I re-evaluate the links attached to the child before calling the method. if (service.UpdateChildParentsLinks(db, currentAnimaltoUpdate, parentInCombo2)) { // test message to be removed MessageBox.Show("Parent 2 has been updated!"); } db.SaveChanges(); MessageBox.Show("Updated record successfull"); } } LoadCurrentZoo(); ClearData(); } } // Using() } else { // None of the fields has been changed before SAVE MessageBox.Show("Nothing to Update"); } }
protected override void Seed(ZooContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. // Add first the Entities on the "one" side // ------------------------------------------- // All Entities around Animal // ------------------------------------------- // Habitats table var habitats = new Habitat[] { new Habitat { HabitatId = 1, Name = "Ground" }, new Habitat { HabitatId = 2, Name = "Tree" }, new Habitat { HabitatId = 3, Name = "Sea" } }; // For each 'habitat' in the list 'habitats' above, // add it to the ICollection Habitats in the context (in other words in the DB) // habitats.ForEach(s => context.Habitats.Add(s)); context.Habitats.AddOrUpdate(x => x.Name, habitats); // Save all changes made in the current context 'ZooContext' to the DB! context.SaveChanges(); // Species Table var species = new Species[] { new Species { Name = "Mammals" }, new Species { Name = "Reptiles" }, new Species { Name = "Birds" } }; // species.ForEach(s => context.Species.Add(s)); context.Species.AddOrUpdate(x => x.Name, species); // Diets table var diets = new Diet[] { new Diet { Name = "Vegetarian" }, new Diet { Name = "Carnivor" }, }; // diets.ForEach(s => context.Diets.Add(s)); context.Diets.AddOrUpdate(x => x.Name, diets); // Origins Table var origins = new Origin[] { new Origin { Name = "Africa" }, new Origin { Name = "Asia" }, new Origin { Name = "North America" }, new Origin { Name = "South America" }, new Origin { Name = "Central America" }, new Origin { Name = "Europe" }, new Origin { Name = "Australia" } }; // origins.ForEach(s => context.Origins.Add(s)); context.Origins.AddOrUpdate(x => x.Name, origins); // ------------------------------------------- // All Entities around Visit // ------------------------------------------- // Diagnosis Table var diagnoses = new Diagnosis[] { new Diagnosis { Description = "Hart failure" }, new Diagnosis { Description = "Low blod pressure" }, new Diagnosis { Description = "Trauma" }, new Diagnosis { Description = "Flu" } }; // Add the collection in the Context and then save in the DB context.Diagnoses.AddOrUpdate(x => x.Description, diagnoses); // Vets Table var veterinaries = new Veterinary[] { new Veterinary { Name = "Francisco Manzano" }, new Veterinary { Name = "Anders Fredriksson" }, new Veterinary { Name = "Lotta Lindeberg" }, new Veterinary { Name = "Helena Lindeberg" } }; context.Veterinaries.AddOrUpdate(x => x.Name, veterinaries); // Drugs Table var drugs = new Drug[] { new Drug { DrugId = 1, Name = "Drug 1" }, new Drug { DrugId = 2, Name = "Drug 2" }, new Drug { DrugId = 3, Name = "Drug 3" }, new Drug { DrugId = 4, Name = "Drug 4" } }; context.Drugs.AddOrUpdate(x => x.Name, drugs); context.SaveChanges(); // -------------------------------------------- // Animals // -------------------------------------------- // NOTE! I JUST NEED TO INITIALIZE THE MAIN PROPERTIES and NOT the Navigation Props! // IMPORTANT!! To avoid FK conflicts, I need to specify placeholders for the IDs otherwise // EF Code First (which assigns by defaul the same value ID=0 to all object) will give error // https://stackoverflow.com/questions/11602683/error-seeding-database-foreign-key-issue var animals = new Animal[] { new Animal() { AnimalId = 1, Name = "Eagle", Weight = 15.1, IsChildOf = new List <ChildParent>(), IsParentOf = new List <ChildParent>() }, new Animal() { AnimalId = 2, Name = "Horse", Weight = 300.3, IsChildOf = new List <ChildParent>(), IsParentOf = new List <ChildParent>() }, new Animal() { AnimalId = 3, Name = "Dog", Weight = 15.4, IsChildOf = new List <ChildParent>(), IsParentOf = new List <ChildParent>() }, new Animal() { AnimalId = 4, Name = "Cat", Weight = 9.0, IsChildOf = new List <ChildParent>(), IsParentOf = new List <ChildParent>() }, new Animal() { AnimalId = 5, Name = "Wale", Weight = 1200.2, IsChildOf = new List <ChildParent>(), IsParentOf = new List <ChildParent>() } }; // ----------------------------------------------------------------------------------------- // Need to create the relations from the "1" side and add the animals BEFORE savingChanges() // ----------------------------------------------------------------------------------------- // Eagle links to Diet, Habitat, Origin & Species animals[0].Diet = diets[1]; animals[0].Origin = origins[2]; animals[0].Habitat = habitats[1]; animals[0].Species = species[2]; // Horse links animals[1].Diet = diets[1]; animals[1].Origin = origins[2]; animals[1].Habitat = habitats[0]; animals[1].Species = species[0]; // Dog links animals[2].Diet = diets[1]; animals[2].Origin = origins[5]; animals[2].Habitat = habitats[0]; animals[2].Species = species[0]; // Cat links animals[3].Diet = diets[1]; animals[3].Origin = origins[5]; animals[3].Habitat = habitats[0]; animals[3].Species = species[0]; // For wale animals[4].Diet = diets[1]; animals[4].Origin = origins[3]; animals[4].Habitat = habitats[2]; animals[4].Species = species[0]; // -------------------- // Create all visits // -------------------- // NOTE! I JUST NEED TO INITIALIZE THE MAIN PROPERTIES and NOT the Navigation Props! // IMPORTANT!! To avoid FK conflicts, I need to specify placeholders for the IDs otherwise // EF Code First (which assigns by defaul the same value ID=0 to all object) will give error // https://stackoverflow.com/questions/11602683/error-seeding-database-foreign-key-issue var visits = new Visit[] { new Visit { VisitId = 1, Start = new DateTime(2016, 10, 02, 10, 15, 45), End = new DateTime(2016, 10, 02, 12, 10, 00), Drugs = new List <VisitDrug>() }, new Visit { VisitId = 2, Start = new DateTime(2017, 03, 16, 08, 30, 00), End = new DateTime(2017, 03, 16, 09, 30, 00), Drugs = new List <VisitDrug>() }, new Visit { VisitId = 3, Start = new DateTime(2017, 09, 12, 15, 00, 00), End = new DateTime(2017, 09, 12, 16, 30, 00), Drugs = new List <VisitDrug>() } }; // ------------------------------------- // Create the Bridge table VisitDrugs // ------------------------------------- // IMPORTANT!! To avoid FK conflicts, I need to specify placeholders for the IDs otherwise // EF Code First (which assigns by defaul the same value ID=0 to all object) will give error // https://stackoverflow.com/questions/11602683/error-seeding-database-foreign-key-issue VisitDrug[] visitDrugs = new VisitDrug[] { new VisitDrug { VisitID = visits[0].VisitId, DrugID = drugs[0].DrugId }, new VisitDrug { VisitID = visits[1].VisitId, DrugID = drugs[2].DrugId }, new VisitDrug { VisitID = visits[2].VisitId, DrugID = drugs[1].DrugId } }; // ----------------------------------------------------------------------------------------- // Need to create the relations from the "1" side and add the visits BEFORE savingChanges() // ----------------------------------------------------------------------------------------- // Linking Visit to Diagnosis, Drugs, Veterinary, Animal // visits[0] visits[0].Diagnosis = diagnoses[0]; visits[0].Veterinary = veterinaries[0]; // visits[0].Drugs.Add(drugs[0]); visits[0].Animal = animals[0]; // visits[1] visits[1].Diagnosis = diagnoses[1]; visits[1].Veterinary = veterinaries[0]; // visits[1].Drugs.Add(drugs[2]); visits[1].Animal = animals[1]; // visits[2] visits[2].Diagnosis = diagnoses[2]; visits[2].Veterinary = veterinaries[1]; // visits[2].Drugs.Add(drugs[1]); visits[2].Animal = animals[2]; // ------------------------------------- // Create the Bridge table ChildParents // ------------------------------------- // IMPORTANT!! To avoid FK conflicts, I need to specify placeholders for the IDs otherwise // EF Code First (which assigns by defaul the same value ID=0 to all object) will give error // https://stackoverflow.com/questions/11602683/error-seeding-database-foreign-key-issue ChildParent[] childparents = new ChildParent[] { new ChildParent { ChildID = animals[0].AnimalId, ParentID = animals[1].AnimalId }, new ChildParent { ChildID = animals[1].AnimalId, ParentID = animals[2].AnimalId }, new ChildParent { ChildID = animals[3].AnimalId, ParentID = animals[2].AnimalId }, new ChildParent { ChildID = animals[4].AnimalId, ParentID = animals[1].AnimalId } }; // Add the Animals & Visits to the Context & Save to DB context.Animals.AddOrUpdate(x => x.Name, animals); // context.Visits.AddOrUpdate(x => x.Start, visits); context.ChildParents.AddOrUpdate(c => new { c.ChildID, c.ParentID }, childparents); // context.VisitDrugs.AddOrUpdate(v => new { v.VisitID, v.DrugID }, visitDrugs); context.SaveChanges(); }