/// <summary> /// Updates a material found by id to match newMaterial. Will validate all the data passed. Expects a full /// Material object to update by. Fields that are to remain the same, should still be passed holding the /// original value. /// </summary> /// <param name="id">The ID of the material</param> /// <param name="newMaterial">The new data wrapped in a Material object</param> /// <returns>The number of rows that were changed</returns> /// /// <exception cref="ArgumentNullException"> /// If any of the Isbn, Title, Language or Description properties /// are null or empty /// </exception> /// /// <exception cref="ArgumentException"> /// If MaterialType, any of MaterialSubjects or any of MaterialAuthors can't /// be found in the database /// </exception> /// /// <remarks>NOT TESTED</remarks> public int Update(int id, Material newMaterial) { var material = FindByID(id); if (material == null) { return(0); } // validate material data if (newMaterial.Isbn.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(newMaterial.Isbn), "ISBN can't be null or empty"); } if (newMaterial.Title.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(newMaterial.Title), "Title can't be null or empty"); } if (newMaterial.Language.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(newMaterial.Language), "Language can't be null or empty"); } if (newMaterial.Description.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(newMaterial.Description), "Description can't be null or empty"); } var materialType = _context.MaterialTypes.Find(newMaterial.Type.TypeId); if (materialType == null) { throw new ArgumentException("MaterialType must already exist", nameof(newMaterial.Type)); } material.Isbn = newMaterial.Isbn; material.Title = newMaterial.Title; material.Language = newMaterial.Language; material.Lendable = newMaterial.Lendable; material.Description = newMaterial.Description; material.Type = materialType; var materialSubjects = newMaterial.MaterialSubjects .Select(ms => { var subject = ms.MaterialSubject; var fetchedSubject = _context.MaterialSubjects.Find(subject.SubjectId); if (fetchedSubject == null) { throw new ArgumentException("MaterialSubjects must already exist", nameof(newMaterial.MaterialSubjects)); } return(new MaterialSubjects { MaterialSubject = fetchedSubject, Material = material }); }).ToList(); var materialAuthors = newMaterial.MaterialAuthors .Select(ma => { var author = ma.Author; var fetchedAuthor = _authorController.FindByID(author.AuthorId); if (fetchedAuthor == null) { if (author.FirstName.IsNullOrEmpty() || author.LastName.IsNullOrEmpty()) { throw new ArgumentNullException( nameof(newMaterial.MaterialAuthors), "New authors must be provided with FirstName AND LastName" ); } var newAuthor = _authorController.Create(author.FirstName, author.LastName); _authorController.Insert(newAuthor); return(new MaterialAuthor { Author = newAuthor, Material = material }); } return(new MaterialAuthor { Author = fetchedAuthor, Material = material }); }).ToList(); // remove previous material subjects _context.RemoveRange(material.MaterialSubjects); material.MaterialSubjects = materialSubjects; // remove pre-existing authors _context.RemoveRange(material.MaterialAuthors); material.MaterialAuthors = materialAuthors; return(_context.SaveChanges()); }