public void Albums_Update(AlbumViewModel item) { DataValidation(item); using (var context = new ChinookSystemContext()) { Album info = new Album() { AlbumId = item.AlbumId, Title = item.AlbumTitle, ArtistId = item.ArtistId, ReleaseYear = item.AlbumReleaseYear, ReleaseLabel = item.AlbumReleaseLabel }; context.Entry(info).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Tracks_Insert(TrackViewModel item) { using (var context = new ChinookSystemContext()) { Track info = new Track() { MediaTypeId = item.TrackMediaTypeId, Name = item.TrackName, Composer = item.TrackComposer, Milliseconds = item.TrackMilliseconds, Bytes = item.TrackBytes, UnitPrice = item.TrackUnitPrice }; context.Tracks.Add(info); context.SaveChanges(); } }
public void Album_Add(AlbumList item) { using (var context = new ChinookSystemContext()) { //moving the data from the external ViewModel instance // into an internal instance of the entity Album addItem = new Album { Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Albums.Add(addItem); context.SaveChanges(); //cases entity validation to run } }
public void Album_Update(AlbumItem item) { using (var context = new ChinookSystemContext()) { Album newItem = new Album { //pkey is identity, not needed AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseLabel = item.ReleaseLabel, ReleaseYear = item.ReleaseYear }; context.Entry(newItem).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Album_Update(AlbumList item) { using (var context = new ChinookSystemContext()) { //moving the data from the external viewmodel instance into an internal instance of the entity Album updateItem = new Album { //Remember for an update, I need to supply the primary key AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Entry(updateItem).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Tracks_Update(TrackViewModel item) { using (var context = new ChinookSystemContext()) { Track info = new Track() { TrackId = item.TrackId, MediaTypeId = item.TrackMediaTypeId, Name = item.TrackName, Composer = item.TrackComposer, Milliseconds = item.TrackMilliseconds, Bytes = item.TrackBytes, UnitPrice = item.TrackUnitPrice }; context.Entry(info).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Album_Update(AlbumList item) { using (var context = new ChinookSystemContext()) { //moving the data from the external ViewModel instance // into an internal instance of the entity Album updateItem = new Album { AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Entry(updateItem).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Album_Add(AlbumItem item) { using (var context = new ChinookSystemContext()) { //move the incoming viewmodel instance data into an instance // of the internal entity Album newItem = new Album { //pkey is identity, not needed Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Albums.Add(newItem); context.SaveChanges(); } }
public void Album_Update(AlbumItem item) { using (var context = new ChinookSystemContext()) { Album updateItem = new Album { //for an update, you need to supply your PK value AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Entry(updateItem).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public void Album_Update(AlbumItem item) { using (var context = new ChinookSystemContext()) { //move the incoming viewmodel instance data into an instance // of the internal entity Album newItem = new Album { //pkey is needed for update to find the instance // on the database AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; context.Entry(newItem).State = System.Data.Entity.EntityState.Modified; context.SaveChanges(); } }
public int Album_Add(AlbumItem item) // this will return PK { using (var context = new ChinookSystemContext()) { //due to the fact that we have separated the handling of our entities // from the data transfer between web app and class library // using the ViewModel classes, we must create an instance // of the entity and move the data from the ViewModel class // to the entity instance Album addItem = new Album { //why no PK set? //PK is an identity PK, no value is needed //However, if PK is NOT an identity spec(Identity Specification = No in the DB), ADD PK here!!! Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; //staging //setup in local memory //at this point you will NOT have sent anything to the database // therefore, you will NOT have your new PK as yet context.Albums.Add(addItem); //commit to database //on this command you // a) execute entity validation annotation // b) send your local memory staging to the database for execution //after a successful execution, your entity instance will have the // new PK (Identity) value context.SaveChanges(); //at this point, your entity instance has the new PK value return(addItem.AlbumId); } }
public void Albums_Update(AlbumItem item) { using (var context = new ChinookSystemContext()) { //need to move the data from the viewmodel class into // an entity instance BEFORE staging //on update you NEED to supply the table's pkey value Album entityItem = new Album { AlbumId = item.AlbumId, Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; //stagging is to local memory context.Entry(entityItem).State = System.Data.Entity.EntityState.Modified; //commit is the action of sending your request to // the database for action. context.SaveChanges(); } }
public int Album_Add(AlbumItem item) { using (var context = new ChinookSystemContext()) { //due to the fact that we have separated the handling of our entities // from the data transfer between web app and class library //using the viewmodel classes, we MUST create an instance //of the entity and move the data from the view model class to the entity instance. Album additem = new Album { //why do we need a pkey set? //pkey is an identity pkey, no value is needed Title = item.Title, ArtistId = item.ArtistId, ReleaseYear = item.ReleaseYear, ReleaseLabel = item.ReleaseLabel }; //staging //setup in local memory //at this point you will not have sent anything to the database // therefore, you will NOT have your new pkey as yet context.Albums.Add(additem); //commit to database //on this command you //A) execute entity validationm annotation // B) send your local memory staging to the database for execution // after a successful execution your entity instance will have the // new pkey (identity) value context.SaveChanges(); //at this point, your identity instance has the new pkey value return(additem.AlbumId); } }
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid) { using (var context = new ChinookSystemContext()) { //the code within this using will be done as a transaction which means there will be ONLY ONE .SaveChanges() within this code. if the .SaveChangs is NOT executed successful, all work within this method will be rollback automatically. //transaction //query:Playlist to see if list name exists //if not //create an instance of playlist //load with data, stage the instance for adding //set the tracknumber to 1 //if yes, check to see if track already exists on Playlist //if found, yes: throw an error (stop processing trx) BUSINESS RULE //no: determine the current max tracknumber, increment++ //create an instance of the PlaylistTrack //load with data, stage the instance for adding //commit the work via entityframework(ADO.net) to the database int tracknumber = 0; PlaylistTrack newtrack = null; List <string> errors = new List <string>();//use for businessrule exception Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (exists == null) { exists = new Playlist() { //pkey is an identity int key Name = playlistname, UserName = username }; context.Playlists.Add(exists); tracknumber = 1; } else {//does the track already exist on the playlist newtrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (newtrack != null) { //throw new Exception("Track already on the playlist. Duplicates not allowed"); errors.Add("Track already on the playlist. Duplicates are not allowed"); } else { tracknumber = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x.TrackNumber).Max(); tracknumber++; } } //create/load/add a playlisttrack newtrack = new PlaylistTrack(); //load of instance data //newtrack.PlaylistId = exists.PlaylistId; newtrack.TrackId = trackid; newtrack.TrackNumber = tracknumber; //scenario 1.new playlist //scenario 2.existing playlist //the solution to both these scenarios is to use navigational properties during the actual .add comand //the entityframework will on your behalf ensure that the adding of records to the database will be done in the appropriate order AND add the missing compound primary key value (playlistId) to the child record newtrack. exists.PlaylistTracks.Add(newtrack); //handle the creation of the PlaylistTrack record //all validation has been passed?? if (errors.Count > 0) { //no, at least one error was found throw new BusinessRuleException("Adding a Track", errors); } else { //good to go //commit all staged work context.SaveChanges(); } } //this ensures that the sql connection closes properly } //eom
} //eom public void MoveTrack(string username, string playlistname, int trackid, int tracknumber, string direction) { using (var context = new ChinookSystemContext()) { //code to go here //check to see if the playlist exists //no:error exception //yes: ////up:check if on the top /////yes:error exception /////no:find record above(tracknumber -1) /////above record tracknumber modified to tracknumber +1 /////selected tracknumber modified to tracknumber-1 ///////down:check if on the bottom /////yes:error exception /////no:find record below(tracknumber +1) /////below record tracknumber modified to tracknumber -1 /////selected tracknumber modified to tracknumber+1 //stage record update //commit List <string> errors = new List <string>();//use for businessrule exception PlaylistTrack moveTrack = null; PlaylistTrack otherTrack = null; Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (exists == null) { errors.Add("Playlist does not exist."); } else { moveTrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (moveTrack == null) { errors.Add("Playlist track does not exist"); } else { if (direction.Equals("up")) { //this means the tracknumber of the selected track will decrease //prep for move, check if the track is at the top of the list if (moveTrack.TrackNumber == 1) { errors.Add("Song on play list already at the top."); } else { otherTrack = (from x in context.PlaylistTracks where x.TrackNumber == (moveTrack.TrackNumber - 1) && x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x).FirstOrDefault(); if (otherTrack == null) { errors.Add("Missing required other song track record."); } else { moveTrack.TrackNumber -= 1; otherTrack.TrackNumber += 1; } } } else { if (moveTrack.TrackNumber == exists.PlaylistTracks.Count) { errors.Add("Song on play list already at the bottom."); } else {//4=>5 otherTrack = (from x in context.PlaylistTracks where x.TrackNumber == (tracknumber + 1) && x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x).FirstOrDefault(); if (otherTrack == null) { errors.Add("Missing required other song track record."); } else { moveTrack.TrackNumber += 1; otherTrack.TrackNumber -= 1; } } } } } if (errors.Count > 0) { throw new BusinessRuleException("Move Track", errors); } else { //stage //1)you can stage an update to alter the entire entity(CRUD) //2)You can stage an update to an entity referencing JUST the property to be modified //in this example (b) will be used context.Entry(moveTrack).Property("TrackNumber").IsModified = true; context.Entry(otherTrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.SaveChanges(); } } }//eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid, string song) { Playlist playlistExists = null; PlaylistTrack playlisttrackExists = null; int tracknumber = 0; using (var context = new ChinookSystemContext()) { //this class is in what is called the "Business Logic Layer" //Business Logic is the rules of your business. //Business Logic ensures that rules and data are what is expected. //Rules: // Rule:A track can only exist once in a Playlist. // Rule:Playlist names can only be used once for a user, different users may have the same playlist name. // Rule:Each track on a playlist is assigned a continious track number // //The BLL method should also ensure that data exists for the processing of the transaction if (string.IsNullOrEmpty(playlistname)) { //there is a data error //setting up an error message: brokenRules.Add(new BusinessRuleException <string>("Playlist name is missing. Unable to add track.", nameof(playlistname), playlistname)); } if (string.IsNullOrEmpty(username)) { //there is a data error //setting up an error message: brokenRules.Add(new BusinessRuleException <string>("User name is missing. Unable to add track.", nameof(username), username)); } //does the playlist already exist? playlistExists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (playlistExists == null) { //new playlist ///Tasks: //// Create a new instance of the playlist class //// Load the instance with data //// Stage the add of the new instnace //// Set the tracknumber to 1 //Create and Load playlistExists = new Playlist() { Name = playlistname, UserName = username }; //Stage context.Playlists.Add(playlistExists); //parent is STAGED tracknumber = 1; } else { //existing playlist ///Tasks: //// Does the track already exist on the playlist? If yes, error. //// If No, find the highest current tracknumber, then increment by 1. playlisttrackExists = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (playlisttrackExists == null) { //track does not exist on the desired playlist. tracknumber = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x.TrackNumber).Count(); tracknumber++; } else { //business rule broken. track DOES exist already on the desired playlist. brokenRules.Add(new BusinessRuleException <string>("Track already on playlist", nameof(song), song)); } } //add the ttrack to the playlist in PlaylistTracks //create an instance playlisttrackExists = new PlaylistTrack(); //load the instance playlisttrackExists.TrackId = trackid; playlisttrackExists.TrackNumber = tracknumber; //add the isntance //??????????????? //What is the playlist id? ///if the playlist exists then we know the id ///BUT if the playlist is NEW, we DO NOT know the id. //in one case the id is known BUT in the second case where the new record is ONLY STAGED, NO primary key // value has been generated yet. <--------------Problem. //if you access the new playlist record the pkey would be 0. // (default numeric value) //the solution to BOTH of these scenarios is to use navigational properties // during the ACTUAL .Add command // for the new playlisttrack record. //the entityframwork will, on your behalf, ensure that the adding of records to the // database will be done in the appropriate order AND will add the missing compound pkey // value (PlaylistId) to the new playlisttrack record. //!!!!!!NOT LIKE THIS !!!!!!! THIS IS WRONG!!!!! //context.PlaylistTracks.Add(playlisttrackExists); //INSTEAD, do the STAGING using the parent.navproperty.Add(xxxx); playlistExists.PlaylistTracks.Add(playlisttrackExists); //do the commit //check to see if ANY business rule exceptions occurred. // if (brokenRules.Count() > 0) { //at least one error was recorded during the processing of the transaction throw new BusinessRuleCollectionException("Add Playlist Track Concerns", brokenRules); } else { //COMMIT THE TRANSACTION //ALL the staged record will be sent to SQL for processing //the transaction is complete //NOTE: A transaction has ONE and ONLY ONE .SaveChanges() context.SaveChanges(); } } }//eom
}//eom public void DeleteTracks(string username, string playlistname, List <int> trackstodelete) { using (var context = new ChinookSystemContext()) { Playlist playlistExists = null; int tracknumber = 0; if (string.IsNullOrEmpty(playlistname)) { //there is a data error //setting up an error message: brokenRules.Add(new BusinessRuleException <string>("Playlist name is missing. Unable to add track.", nameof(playlistname), playlistname)); } if (string.IsNullOrEmpty(username)) { //there is a data error //setting up an error message: brokenRules.Add(new BusinessRuleException <string>("User name is missing. Unable to remove track(s)", "User Name", username)); } if (trackstodelete.Count == 0) { //there is a data error //setting up an error message: brokenRules.Add(new BusinessRuleException <int>("Playlist name is missing. Unable to remove track(s)", "Track list count", 0)); } playlistExists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (playlistExists == null) { brokenRules.Add(new BusinessRuleException <string>("Playlist does not exist.", nameof(playlistname), playlistname)); } else { //list of all tracks that are to be kept var trackskept = context.PlaylistTracks .Where(x => x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && !trackstodelete.Any(tod => tod == x.TrackId)) .OrderBy(x => x.TrackNumber) .Select(x => x); //remove the desired tracks PlaylistTrack item = null; foreach (var deleterecord in trackstodelete) //tracksids to delete { //getting a single record item = context.PlaylistTracks .Where(x => x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == deleterecord) .Select(x => x).FirstOrDefault(); //delete //stage (parent.navproperty.Remove() if (item != null) { playlistExists.PlaylistTracks.Remove(item); } } //re-sequence the kept tracks //Option A) use a list and update the records of the list. //Option B) delete all children records and re-add only the necessary kept records. //within this example, you will see how to update specific column(s) of a record. (OptionA) tracknumber = 1; foreach (var track in trackskept) { track.TrackNumber = tracknumber; //Stage the update context.Entry(track).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; tracknumber++; } } //commit? if (brokenRules.Count > 0) { throw new BusinessRuleCollectionException("Track Removal Concerns:", brokenRules); } else { context.SaveChanges(); } } }//eom
}//eom public void MoveTrack(MoveTrackItem movetrack) { int numberoftracks = 0; using (var context = new ChinookSystemContext()) { if (string.IsNullOrEmpty(movetrack.PlaylistName)) { //there is a data error //setting up an error message brokenRules.Add(new BusinessRuleException <string>("Playlist name is missing. Unable to remove track(s)", "Playlist Name", movetrack.PlaylistName)); } if (string.IsNullOrEmpty(movetrack.UserName)) { //there is a data error //setting up an error message brokenRules.Add(new BusinessRuleException <string>("User name is missing. Unable to remove track(s)", "User Name", movetrack.UserName)); } if (movetrack.TrackID <= 0) { brokenRules.Add(new BusinessRuleException <int>("Invalid track identifier. Unable to remove track(s)", "Track Identifier", movetrack.TrackID)); } if (movetrack.TrackNumber <= 0) { brokenRules.Add(new BusinessRuleException <int>("Invalid track number. Unable to remove track(s)", "Track Number", movetrack.TrackNumber)); } Playlist exist = (from x in context.Playlists where x.Name.Equals(movetrack.PlaylistName) && x.UserName.Equals(movetrack.UserName) select x).FirstOrDefault(); if (exist == null) { brokenRules.Add(new BusinessRuleException <string>("Playlist does not exist.", nameof(MoveTrackItem.PlaylistName), movetrack.PlaylistName)); } else { //due to the way that LInq executes in your program as a "lazy loader" //we need to query directly the number of tracks in the playlist numberoftracks = (context.PlaylistTracks .Where(x => x.Playlist.Name.Equals(movetrack.PlaylistName) && x.Playlist.UserName.Equals(movetrack.UserName)) .Select(x => x)).Count(); //check to see if the desired track exists on the database PlaylistTrack trackexist = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(movetrack.PlaylistName) && x.Playlist.UserName.Equals(movetrack.UserName) && x.TrackId == movetrack.TrackID select x).FirstOrDefault(); if (trackexist == null) { brokenRules.Add(new BusinessRuleException <string>("Playlist track does not exist.", nameof(MoveTrackItem.PlaylistName), movetrack.PlaylistName)); } else { //decide the logic depending on direction if (movetrack.Direction.Equals("up")) { //up //not at top if (trackexist.TrackNumber == 1) { brokenRules.Add(new BusinessRuleException <string>("Playlist track already at the top. Refresh your display.", nameof(Track.Name), trackexist.Track.Name)); } else { //do the move //get the adjacent track PlaylistTrack othertrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(movetrack.PlaylistName) && x.Playlist.UserName.Equals(movetrack.UserName) && x.TrackNumber == trackexist.TrackNumber - 1 select x).FirstOrDefault(); if (othertrack == null) { brokenRules.Add(new BusinessRuleException <string>("Playlist track to swap seems to be missing. Refresh your display.", nameof(MoveTrackItem.PlaylistName), movetrack.PlaylistName)); } else { //good to swap //the swap is a matter of changing the tracknumber values trackexist.TrackNumber -= 1; othertrack.TrackNumber += 1; //staging context.Entry(trackexist).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(othertrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } } } else { //down //not at bottom if (trackexist.TrackNumber == numberoftracks) { brokenRules.Add(new BusinessRuleException <string>("Playlist track already at the bottom. Refresh your display.", nameof(Track.Name), trackexist.Track.Name)); } else { //do the move //get the adjacent track PlaylistTrack othertrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(movetrack.PlaylistName) && x.Playlist.UserName.Equals(movetrack.UserName) && x.TrackNumber == trackexist.TrackNumber + 1 select x).FirstOrDefault(); if (othertrack == null) { brokenRules.Add(new BusinessRuleException <string>("Playlist track to swap seems to be missing. Refresh your display.", nameof(MoveTrackItem.PlaylistName), movetrack.PlaylistName)); } else { //good to swap //the swap is a matter of changing the tracknumber values trackexist.TrackNumber += 1; othertrack.TrackNumber -= 1; //staging context.Entry(trackexist).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(othertrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } } } } } //commit? if (brokenRules.Count > 0) { throw new BusinessRuleCollectionException("Track Movement Concerns:", brokenRules); } else { context.SaveChanges(); } } }//eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid) { using (var context = new ChinookSystemContext()) { //the code within this using wil be done as a Transaction which means // there will be ONLY ONE .SaveChanges() within this code. //if the .SaveChanges is NOT executed successful, all work // within this method will be rollback automatically! //trx //query: PlayList to see if list name exists //if not // create an instance of Playlist // load with data // stage the instance for adding // set the tracknumber to 1 //if yes // check to see if track already exists on playlist // if found // no: determine the current max tracknumber, increment++ // yes: throw an error (stop processing trx) BUSINESS RULE //create an instance of the PlaylistTrack // load with data // stage the instance for adding //commit the work via entityframework (ADO.net) to the database int tracknumber = 0; PlaylistTrack newtrack = null; List <string> errors = new List <string>(); //for use by BusinessRuleException Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (exists == null) { //exists = new Playlist(); //exists.Name = playlistname; //exists.UserName = username; exists = new Playlist() { //pkey is an identity int key Name = playlistname, UserName = username }; context.Playlists.Add(exists); tracknumber = 1; } else { //exists has the record instance of the playlist //does the track already exist on the playlist newtrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (newtrack == null) { //track not on playlist tracknumber = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x.TrackNumber).Max(); tracknumber++; } else { //track already on playlist //business rule states duplicate tracks on playlist not allowed //violates the busines rule //throw an exception //throw new Exception("Track already on the playlist. Duplicates not allowed"); //use the BusinessRuleException class to throw the error //this class takes in a List<string> representing all errors to the handled errors.Add("Track already on the playlist. Duplicates are not allowed"); } } //create/load/add a PlaylistTrack newtrack = new PlaylistTrack(); //load of instance data newtrack.TrackId = trackid; newtrack.TrackNumber = tracknumber; //scenario 1) New playlist // the exists instance is a NEW instance that is YET // to be placed on the sql database // THEREFORE it DOES NOT YET have a primary key value!!!!!!! // the current value of the PlaylistId on the exists instance // is the default system value for an integer (0) //scenario 2) Existing playlist // the exists instance has the PlaylistId value //the solution to both these scenarios is to use // navigational properties during the ACTUAL .Add command //the entityframework will on your behave ensure that the // adding of records to the database will be done in the // appropriate order AND add the missing compound primary key // value (PlaylistId) to the child record newtrack; exists.PlaylistTracks.Add(newtrack); //handle the creation of the PlaylistTrack record //all validation has been passed???? if (errors.Count > 0) { //no, at least one error was found throw new BusinessRuleException("Adding a Track", errors); } else { //good to go //COMMITTING all staged work context.SaveChanges(); } } //this ensures that the sql connection closes properly } //eom
}//eom public void DeleteTracks(string username, string playlistname, List <int> trackstodelete) { using (var context = new ChinookSystemContext()) { //trx //check to see if playlist exists // no: error msg // yes: // create a list of tracks to kept // remove the tracks in the incoming list // re-sequence the kept tracks // commit List <string> errors = new List <string>(); //for use by BusinessRuleException Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (exists == null) { errors.Add("Play list does not exist."); } else { //find the songs to keep var trackskept = context.PlaylistTracks .Where(tr => tr.Playlist.Name.Equals(playlistname) && tr.Playlist.UserName.Equals(username) && !trackstodelete.Any(tod => tod == tr.TrackId)) .OrderBy(tr => tr.TrackNumber) .Select(tr => tr); //remove the tracks to delete PlaylistTrack item = null; foreach (int deletetrackid in trackstodelete) { item = context.PlaylistTracks .Where(tr => tr.Playlist.Name.Equals(playlistname) && tr.Playlist.UserName.Equals(username) && tr.TrackId == deletetrackid) .Select(tr => tr).FirstOrDefault(); if (item != null) { //stage the delete exists.PlaylistTracks.Remove(item); } } //re-sequence int number = 1; foreach (var track in trackskept) { track.TrackNumber = number; context.Entry(track).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; number++; } if (errors.Count > 0) { throw new BusinessRuleException("Track removal", errors); } else { //commit context.SaveChanges(); } } } }//eom
}//eom public void MoveTrack(MoveTrackItem moveTrack) { using (var context = new ChinookSystemContext()) { //code to go here if (string.IsNullOrEmpty(moveTrack.PlaylistName)) { //there is a data error //setting up an error message //brokenRules.Add(new BusinessRuleException<datatype>("my message", //nameof("fieldnameinerror"), fieldnameinerror)); brokenRules.Add(new BusinessRuleException <string>("playlist name is missing, Unable to add track", "Playlist Name", moveTrack.PlaylistName)); } if (string.IsNullOrEmpty(moveTrack.UserName)) { brokenRules.Add(new BusinessRuleException <string>("username is missing, Unable to add a track", "User Name", moveTrack.UserName)); } if (moveTrack.TrackId <= 0) { brokenRules.Add(new BusinessRuleException <int>("Invalid track identifier, Unable to move a track", "Track Identifier", moveTrack.TrackId)); } if (moveTrack.TrackNumber <= 0) { brokenRules.Add(new BusinessRuleException <int>("Invalid track number, Unable to move a track(s)", "Track Number", moveTrack.TrackNumber)); } Playlist exist = context.Playlists.Where(x => x.Name.Equals(moveTrack.PlaylistName) && x.UserName.Equals(moveTrack.UserName)).FirstOrDefault(); if (exist == null) { brokenRules.Add(new BusinessRuleException <string>("playlist does not exist", nameof(MoveTrackItem.PlaylistName), moveTrack.PlaylistName)); } else { //list of all tracks to be kept //Chec PlaylistTrack trackExist = context.PlaylistTracks.Where(x => x.Playlist.Name.Equals(moveTrack.PlaylistName) && x.TrackId == moveTrack.TrackId && x.Playlist.UserName.Equals(moveTrack.UserName) && x.TrackNumber == moveTrack.TrackNumber).FirstOrDefault(); if (trackExist == null) { brokenRules.Add(new BusinessRuleException <string>("track name does not exist", "Track Name", moveTrack.PlaylistName)); } else { if (moveTrack.Direction.Equals("up")) { if (trackExist.TrackNumber == 1) { brokenRules.Add(new BusinessRuleException <string>("playlist trac k already on the top.Refresh your display", nameof(Track.Name), trackExist.Track.Name)); } else { //do tthe moeve //get the adajacent track PlaylistTrack otherTrack = context.PlaylistTracks.Where(x => x.Playlist.Name.Equals(moveTrack.PlaylistName) && x.Playlist.UserName.Equals(moveTrack.UserName) && x.TrackNumber == (trackExist.TrackNumber - 1)).Select(x => x).FirstOrDefault(); if (otherTrack == null) { brokenRules.Add(new BusinessRuleException <string>("playlist to swap seems to be missing.Refresh your display", nameof(MoveTrackItem.PlaylistName), moveTrack.PlaylistName)); } else { //good to swap //the swap is a mattter of changing track number value trackExist.TrackNumber--; otherTrack.TrackNumber++; //staging context.Entry(trackExist).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(otherTrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } } } else { //down if (moveTrack.Direction.Equals("down")) { var play = context.PlaylistTracks.Where(x => x.Playlist.Name.Equals(moveTrack.PlaylistName) && x.Playlist.UserName.Equals(moveTrack.UserName)).Count(); if (trackExist.TrackNumber == play) { brokenRules.Add(new BusinessRuleException <string>("playlist track already on the bottom.Refresh your display", nameof(Track.Name), trackExist.Track.Name)); } else { //do tthe moeve //get the adajacent track PlaylistTrack otherTrack = context.PlaylistTracks.Where(x => x.Playlist.Name.Equals(moveTrack.PlaylistName) && x.Playlist.UserName.Equals(moveTrack.UserName) && x.TrackNumber == (trackExist.TrackNumber + 1)).Select(x => x).FirstOrDefault(); if (otherTrack == null) { brokenRules.Add(new BusinessRuleException <string>("playlist to swap seems to be missing.Refresh your display", nameof(MoveTrackItem.PlaylistName), moveTrack.PlaylistName)); } else { //good to swap //the swap is a mattter of changing track number value trackExist.TrackNumber++; otherTrack.TrackNumber--; //staging context.Entry(trackExist).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(otherTrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } } } } } //remove the desired tracks if (brokenRules.Count > 0) { throw new BusinessRuleCollectionException("Track Move concerns: ", brokenRules); } else { context.SaveChanges(); } } } }//eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid, string song) { //early var placeholders Playlist playlistExist = null; PlaylistTrack playlistTrackExist = null; int tracknumber = 0; using (var context = new ChinookSystemContext()) { //ensure data recieved - this class is in BLL and must enforce business rules //rules - no song repetition in playlists // - playlist name must be unique to the user // - each track on a playlist is assigned a continous track number -- track number id on playlist //BLL must ensure that data exists for processing transaction if (string.IsNullOrEmpty(playlistname)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("playlist name is missing. unable to add track", nameof(playlistname), playlistname)); //nameof not requires if specific } if (string.IsNullOrEmpty(username)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("username name is missing. unable to add track", "username", username)); } if (brokenrules.Count() == 0) { //does the playlist already exist? -- return null or first -- should only be one playlistExist = (from x in context.Playlists where x.Name == playlistname && x.UserName == username select x).FirstOrDefault(); if (playlistExist == null) { //new playlist //tasks - create a new playlist class instance // load instance with data //stage the playlist instance // set track number - 1 playlistExist = new Playlist() { Name = playlistname, UserName = username, }; context.Playlists.Add(playlistExist); //staged in memory tracknumber = 1; } else { //existing playlist //tasks - // does the track exist? - error if yes // what is the last track number? // insert track ++tracknumber playlistTrackExist = (from x in context.PlaylistTracks where x.Playlist.Name == playlistname && x.Playlist.UserName == username && x.TrackId == trackid select x).FirstOrDefault(); //look for track if (playlistTrackExist == null) { //track does not exist on desired playlist //find highest track number and incriment tracknumber = (from x in context.PlaylistTracks where x.Playlist.Name == playlistname && x.Playlist.UserName == username select x.TrackNumber).Count(); tracknumber++; //add track to playlist } else { //business rule broken. track DOES exist on playlist. brokenrules.Add(new BusinessRuleException <string>("Track already on playlist", nameof(song), song)); // showing the data causing error } } //create instance playlistTrackExist = new PlaylistTrack(); //load instance playlistTrackExist.TrackId = trackid; playlistTrackExist.TrackNumber = tracknumber; //SQL CREATING PK //where new record is ONLY staged there is no PK value. // if you access the new playlist record the PK would default of 0 <--- bad //stage parent with track item //entity framework will ensure that the adding of records to the database will be done in // the appropriate order and will add the missing compound PK value (playlistId) to the new playlist track record //add instance //THIS IS CORRECT, USING NAVIGATIONAL PROPERTIES to stage playlistExist.PlaylistTracks.Add(playlistTrackExist); } //check again for errors up to this point if (brokenrules.Count() == 0) { //do the commit //all the staged records will be sent to SQL for processing context.SaveChanges(); //note COMPLETED transaction - 1 and only 1 .savechanges() } // broken rules exist else { throw new BusinessRuleCollectionException("Adding playlist Track concerns", brokenrules); //title and exception list } } }//eom
}//eom public void MoveTrack(MoveTrackItem movetrack) { using (var context = new ChinookSystemContext()) { //inital value errorchecking if (string.IsNullOrEmpty(movetrack.PlaylistName)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("playlist name is missing. unable to delete track", nameof(movetrack.PlaylistName), movetrack.PlaylistName)); //nameof not requires if specific } if (string.IsNullOrEmpty(movetrack.UserName)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("username name is missing. unable to delete track", "username", movetrack.UserName)); } if (movetrack.TrackID <= 0) { brokenrules.Add(new BusinessRuleException <string>("trackID no bueno", "trackID", movetrack.TrackID.ToString())); } if (movetrack.TrackNumber <= 0) { brokenrules.Add(new BusinessRuleException <string>("trackID no bueno", "track Number", movetrack.TrackNumber.ToString())); } Playlist exist = (from x in context.Playlists where x.Name == movetrack.PlaylistName && x.UserName == movetrack.UserName select x).FirstOrDefault(); if (exist == null) { //broken rule brokenrules.Add(new BusinessRuleException <string>("playlist no exist", nameof(movetrack.PlaylistName), movetrack.PlaylistName)); } else { //check if track exists on the database PlaylistTrack trackexists = (from x in context.PlaylistTracks where x.Playlist.Name == movetrack.PlaylistName && x.Playlist.UserName == movetrack.UserName && x.TrackId == movetrack.TrackID select x).FirstOrDefault(); if (trackexists == null) { //broken rule brokenrules.Add(new BusinessRuleException <string>("playlist track no exist", nameof(movetrack.TrackID), movetrack.TrackNumber.ToString())); //should lookup name. } else { //move it up or move it down if (movetrack.Direction == "up") { //up //check to see if at top - != 1 if (trackexists.TrackNumber != 1) { // do the move //get adjacent track PlaylistTrack othertrack = (from x in context.PlaylistTracks where x.Playlist.Name == movetrack.PlaylistName && x.Playlist.UserName == movetrack.UserName && x.TrackNumber == trackexists.TrackNumber - 1 select x).FirstOrDefault(); //check other track exists if (othertrack != null) { //good to swap //swap is a matter of changing the track Number Values trackexists.TrackNumber--; othertrack.TrackNumber++; //stage context.Entry(trackexists).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(othertrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } else { //broken rule brokenrules.Add(new BusinessRuleException <string>("track to swap is missing", nameof(othertrack.Track.Name), othertrack.Track.Name)); } } else { //broken rule brokenrules.Add(new BusinessRuleException <string>("playlist track already #1, refresh display", nameof(movetrack.PlaylistName), trackexists.Track.Name)); } } else { int trackcountonexist = (from x in context.Playlists where x.Name == movetrack.PlaylistName && x.UserName == movetrack.UserName select x).FirstOrDefault().PlaylistTracks.ToList().Count(); trackcountonexist++; //lazy loader bullshi...... //down //up //check to see if at Bottom - != count of the existing playlist if (trackexists.TrackNumber != trackcountonexist--) { // do the move //get adjacent track PlaylistTrack othertrack = (from x in context.PlaylistTracks where x.Playlist.Name == movetrack.PlaylistName && x.Playlist.UserName == movetrack.UserName && x.TrackNumber == trackexists.TrackNumber + 1 select x).FirstOrDefault(); //check other track exists if (othertrack != null) { //good to swap //swap is a matter of changing the track Number Values trackexists.TrackNumber++; othertrack.TrackNumber--; //stage context.Entry(trackexists).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; context.Entry(othertrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; } else { //broken rule brokenrules.Add(new BusinessRuleException <string>("track to swap is missing", nameof(othertrack.Track.Name), othertrack.Track.Name)); } } else { //broken rule brokenrules.Add(new BusinessRuleException <string>("playlist track already #1, refresh display", nameof(movetrack.PlaylistName), trackexists.Track.Name)); } } } } //resequence the kept tracks // option - use a list and update the records of the list //option - delete all children records and re-add only the new kept records list //commit if (brokenrules.Count > 0) { throw new BusinessRuleCollectionException("Track movement concerns", brokenrules); } else { context.SaveChanges(); } } }//eom
}//eom public void DeleteTracks(string username, string playlistname, List <int> trackstodelete) { Playlist playlistExist = null; //PlaylistTrack playlisttrackExist = null; int trackNumber = 0; using (var context = new ChinookSystemContext()) { //code to go here if (string.IsNullOrEmpty(playlistname)) { //there is a data error //setting up an error message //brokenRules.Add(new BusinessRuleException<datatype>("my message", //nameof("fieldnameinerror"), fieldnameinerror)); brokenRules.Add(new BusinessRuleException <string>("playlist name is missing, Unable to add track", "Playlist Name", playlistname)); } if (string.IsNullOrEmpty(username)) { brokenRules.Add(new BusinessRuleException <string>("username is missing, Unable to add a track", "User Name", username)); } if (trackstodelete.Count == 0) { brokenRules.Add(new BusinessRuleException <int>("No tracks we selected. Unable to remove track(s)", "Track list count", 0)); } playlistExist = context.Playlists.Where(x => x.Name.Equals(playlistname) && x.UserName.Equals(username)).FirstOrDefault(); if (playlistExist == null) { brokenRules.Add(new BusinessRuleException <string>("playlist does not exist", nameof(playlistname), playlistname)); } else { //list of all tracks to be kept var trackskept = context.PlaylistTracks.Where(x => x.Playlist.UserName.Equals(username) && x.Playlist.Name.Equals(trackNumber) && !trackstodelete.Any(tod => tod == x.TrackId)).OrderBy(x => x.TrackNumber).Select(x => x).ToList(); //remove the desired tracks PlaylistTrack item = null; foreach (var deleteRecord in trackstodelete) { item = context.PlaylistTracks.Where(x => x.Playlist.UserName.Equals(username) && x.Playlist.Name.Equals(trackNumber) && x.TrackId == deleteRecord).FirstOrDefault(); //delete //stage (parent.navproperty.remove) if (item != null) { playlistExist.PlaylistTracks.Remove(item); } } //re-sequence the list //option a) use a list and update the records of the list //option b) to delete all children records and re add onl the necessary kept records //Within this example, you'll see an update specific columns of a records(option a) trackNumber = 1; foreach (var track in trackskept) { track.TrackNumber = trackNumber; //stage a single field to be updated context.Entry(track).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; trackNumber++; } } //commit? if (brokenRules.Count > 0) { throw new BusinessRuleCollectionException("Track Removal concerns: ", brokenRules); } else { context.SaveChanges(); } } }//eom
}//eom public void MoveTrack(string username, string playlistname, int trackid, int tracknumber, string direction) { using (var context = new ChinookSystemContext()) { //code to go here // since data can be accessed by multiple individuals at the same time // your BLL method should do validation to ensure the data coming is appropriate var exists = context.Playlists.Where(x => x.UserName.Equals(username) && x.Name.Equals(playlistname)).Select(x => x).FirstOrDefault(); // playlist no longer exists if (exists == null) { throw new Exception("Playlist has been removed from files."); } else { var movetrack = exists.PlaylistTracks.Where(x => x.TrackId == trackid).Select(x => x).FirstOrDefault(); //playlist track no longer exists if (movetrack == null) { throw new Exception("Playlist track has been removed from files - Movetrack."); } else { PlaylistTrack othertrack = null; // determine direction if (direction.Equals("up")) { if (movetrack.TrackNumber == 1) { throw new Exception("Playlist track already at top."); } else { //setup for track movement othertrack = (from x in exists.PlaylistTracks where x.TrackNumber == movetrack.TrackNumber - 1 select x).FirstOrDefault(); if (othertrack == null) { throw new Exception("Playlist tracks have been altered. Unable to Complete move"); } else { movetrack.TrackNumber -= 1; othertrack.TrackNumber += 1; } } } else { if (movetrack.TrackNumber == exists.PlaylistTracks.Count) { throw new Exception("Playlist track already at last."); } else { //setup for track movement othertrack = (from x in exists.PlaylistTracks where x.TrackNumber == movetrack.TrackNumber + 1 select x).FirstOrDefault(); if (othertrack == null) { throw new Exception("Playlist tracks have been altered. Unable to Complete move"); } else { movetrack.TrackNumber += 1; othertrack.TrackNumber -= 1; } } } //staging //update context.Entry(movetrack).Property(y => y.TrackNumber).IsModified = true; context.Entry(othertrack).Property(y => y.TrackNumber).IsModified = true; //commit context.SaveChanges(); } } } }//eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid, string song) { Playlist playlistExist = null; PlaylistTrack playlistTrackExist = null; int trackNumber = 0; using (var context = new ChinookSystemContext()) { //this class is in what is called the Business Logic Layer //Business Logic is the rules of your business //Business Logic ensures that rules and data are what is expected //Rules: a track can only exist once on a playlist, playlist names can only be used once for a user, different users may have the same playlist name, each track on a playlist is assigned a continuous track number //The BLL method should ensure that data exists for the processing of the transaction if (string.IsNullOrEmpty(playlistname)) { //there is a data error //setting up an error message brokenRules.Add(new BusinessRuleException <string>("Playlist name is missing. Unable to add track", "Playlist Name", playlistname)); } if (string.IsNullOrEmpty(username)) { //there is a data error //setting up an error message brokenRules.Add(new BusinessRuleException <string>("Username is missing. Unable to add track", "User name", username)); } //does the playlist already exist? playlistExist = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); if (playlistExist == null) { //new playlist //tasks: create a new instance of the playlist class, load the instance with data, stage the add of the new instance, set the tracknumber to 1 playlistExist = new Playlist() { Name = playlistname, UserName = username }; context.Playlists.Add(playlistExist); //parent is staged trackNumber = 1; } else { //existing playlist //tasks: does the track already exist on the playlist? if so, error //if not, find the highest current tracknumber, increment by 1 (rule) playlistTrackExist = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (playlistTrackExist == null) { //track does not exist on the desired playlist trackNumber = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x.TrackNumber).Count(); trackNumber++; } else { //business rule broken, track does exist on the desired playlist brokenRules.Add(new BusinessRuleException <string>("Track already on playlist", nameof(song), song)); } } //add the track to the playlist in PlaylistTracks //create an instance playlistTrackExist = new PlaylistTrack(); //load the instance playlistTrackExist.TrackId = trackid; playlistTrackExist.TrackNumber = trackNumber; //??????????? //What is the playlist id //if the playlist exists then we know the id //but if the playlist is new, we do not know the id //in one case the id is known BUT in the second case where the new record is ONLY STAGED, NO primary key value has been generated yet <-- problems //if you access the new playlist record the pkey would be 0 (default numeric value) //the solution to both of these scenarios is to use navigational properties during the ACTUAL .add command for the new playlisttrack record //the entityframework will, on your behalf, ensure that the adding of records to the database will be done in the appropriate order AND will add the missing compound pkey value (PlaylistId) to the new playlisttrack record //NOT LIKE THIS!!! THIS IS WRONG //context.PlaylistTracks.Add(playlistTrackExist); //instead, do staging using the parent.navproperty.Add(xxx) playlistExist.PlaylistTracks.Add(playlistTrackExist); //add the instance //do the commit //check to see if any rule exceptions occured if (brokenRules.Count() > 0) { //at least one record was recorded during the processing of the transaction throw new BusinessRuleCollectionException("Add Playlist Track Concerns", brokenRules); } else { //COMMIT THE TRANSACTION //all the staged records will be sent to sql for processing //the transaction is complete //NOTE: a transaction has ONE AND ONLY ONE .SaveChanges() context.SaveChanges(); } } }//eom
}//eom public void DeleteTracks(string username, string playlistname, List <int> trackstodelete) { //early var placeholders Playlist playlistExist = null; PlaylistTrack playlistTrackExist = null; int tracknumber = 0; using (var context = new ChinookSystemContext()) { if (string.IsNullOrEmpty(playlistname)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("playlist name is missing. unable to delete track", nameof(playlistname), playlistname)); //nameof not requires if specific } if (string.IsNullOrEmpty(username)) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("username name is missing. unable to delete track", "username", username)); } if (trackstodelete.Count == 0) { //no playlist name supplied -error out //BusinessRuleException -- part of freecode -import brokenrules.Add(new BusinessRuleException <string>("tracks to delete. unable to delete track", "track count", trackstodelete.Count.ToString())); } playlistExist = (from x in context.Playlists where x.Name == playlistname && x.UserName == username select x).FirstOrDefault(); if (playlistExist == null) { //broken rule brokenrules.Add(new BusinessRuleException <string>("playlist no exist", nameof(playlistname), playlistname)); } else { //good data //list all tracks that are to be kept //compare lists of delete to list of kept var trackskept = from x in context.PlaylistTracks where x.Playlist.Name == playlistname && x.Playlist.UserName == username && !trackstodelete.Any(tod => tod == x.TrackId) orderby x.TrackNumber select x; //remove the desired track refrences PlaylistTrack item = null; foreach (var deleterecord in trackstodelete) { item = (from x in context.PlaylistTracks where x.Playlist.Name == playlistname && x.Playlist.UserName == username && x.TrackId == deleterecord orderby x.TrackNumber select x).FirstOrDefault(); if (item != null) { //delete //stage via parent.nav.remove() playlistExist.PlaylistTracks.Remove(item); } } //resequence the kept tracks // option - use a list and update the records of the list //option - delete all children records and re-add only the new kept records list tracknumber = 1; foreach (var track in trackskept) { track.TrackNumber = tracknumber; //stage context.Entry(track).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; tracknumber++; } //commit if (brokenrules.Count > 0) { throw new BusinessRuleCollectionException("Track removal concerns", brokenrules); } else { context.SaveChanges(); } } } }//eom
} //eom public void MoveTrack(string username, string playlistname, int trackid, int tracknumber, string direction) { using (var context = new ChinookSystemContext()) { //trx //check to see if the playlist exists //no: error exception //yes: // Check to see if song exists // no: error exception // yes: //// //up: //// //check to see if song is at the top //// //yes: error exception //// // no: //// //find record above (tracknumber-1 //// //change above record tracknumber modified to tracknumber + 1 //// //selected record tracnumber modified to tracknumbere - 1 //// //down: //// //check to see if song is at the botom //// //yes: error exception //// //no: //// //find record above (tracknumber+1 //// //change above record tracknumber modified to tracknumber - 1 //// //selected record tracnumber modified to tracknumbere + 1 ////stage records //commit PlaylistTrack moveTrack = null; PlaylistTrack otherTrack = null; List <string> errors = new List <string>(); //for use by BusinessRuleException Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); //if not if (exists == null) { errors.Add("Playlist does not exist"); } else { moveTrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (moveTrack == null) { errors.Add("Playlist track does not exist"); } else { if (direction.Equals("up")) //Move Uo { //this means the track number of the selectred track // will decrease (track 4 => 3) //preparation for move, check if the track is at the top of the list if (moveTrack.TrackNumber == 1) { errors.Add("song on playlist already at the top"); } else { //Manipulation of the actual records //the following test conditions identify the playlistID value // x.Playlist.Name.Equals(playlistname) // x.Playlist.UserName.Equals(username) otherTrack = (from x in exists.PlaylistTracks where x.TrackNumber == tracknumber - 1 && x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x).FirstOrDefault(); if (otherTrack == null) { errors.Add("Missing required other song record."); } else { moveTrack.TrackNumber -= 1; otherTrack.TrackNumber += 1; } } } else //Move Down { if (moveTrack.TrackNumber == exists.PlaylistTracks.Count) { errors.Add("song on playlist already at the bottom"); } else { //Manipulation of the actual records //(track 4->5) otherTrack = (from x in exists.PlaylistTracks where x.TrackNumber == tracknumber + 1 && x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x).FirstOrDefault(); if (otherTrack == null) { errors.Add("Missing required other song record."); } else { moveTrack.TrackNumber += 1; otherTrack.TrackNumber -= 1; } } } } } if (errors.Count > 0) { throw new BusinessRuleException("Move Track", errors); } else { //stage changes //a)you can stage an update to alter the entire entity //b) you can stage an update to an entity referencing JUST the property // to be modified //in this example B will be used context.Entry(moveTrack).Property("TrackNumber").IsModified = true; context.Entry(otherTrack).Property(nameof(PlaylistTrack.TrackNumber)).IsModified = true; //commit context.SaveChanges(); } } }//eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid) { using (var context = new ChinookSystemContext()) { //code within this using will be done as a transaction which // means there will be ONLY ONE .SaveChanges() within this code. //If the .SaveChanges() is NOT executed successfully, all work // within this method will be rolled back AUTOMATICALLY!!!!!! //trx //Query: PlayList to see if list name exists int trackNumber = 0; PlaylistTrack newtrack = null; List <string> errors = new List <string>(); //for use by BusinessRuleException Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); //if not if (exists == null) { // Create an instance of the PlayList // exists = new Playlist() // exists.Name = playlistname, // exists.UserName = username exists = new Playlist() { // Load instance with data //pkey is an identity int key Name = playlistname, UserName = username }; // Stage the instance for adding context.Playlists.Add(exists); // set the tracknumber to 1 trackNumber = 1; } //if yes else { // check to see if the track already exists on the playlist //exist has the record instance of the playlist //does the track already exist on the playlist newtrack = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) && x.TrackId == trackid select x).FirstOrDefault(); if (newtrack == null) { //track not on playlist // no: Determine the current max tracknumber and increment++ trackNumber = (from x in context.PlaylistTracks where x.Playlist.Name.Equals(playlistname) && x.Playlist.UserName.Equals(username) select x.TrackNumber).Max(); trackNumber++; } else { // if found // yes: throw an error (stop processing trx) Business Rule // track on playlist //Business rull does not allow for duplicates tracks on playlist //throw an exception //throw new Exception("Track already on playlists. Duplicates not allowed."); //use a BusinessRuleException class to throw the error //this class takes in a List<string> representin all errors to be handled errors.Add("Track already on playlists. Duplicates not allowed."); } } //create/load/add a PlaylistTrack newtrack = new PlaylistTrack(); //load instance Data newtrack.TrackId = trackid; newtrack.TrackNumber = trackNumber; //scenario 1. This is a New playlist // the exists instance is a new instance that is YET // to be placed on the SQL database // THEREFORE it DOES NOT yet have a primary key value!!!!!!!! // the current value of the playlistId on the exist instance // is the Default system value for an integer(0) //scenario 2. This is an existing playlist // the exists instance has the playlist ID value //the solution to both these scenarios is to use // navigational properties during the ACTUAL .Add command //the entityframework will, on your behalf, ensure that the // adding of records to the database will be done in the // appropriate order and the missing compound primary key // value(playlistId) to the child record new track exists.PlaylistTracks.Add(newtrack); //Staged Data //Handle creation of playlist track record //all validation has been passed?????????? if (errors.Count() > 0) { //NO, at least one error found throw new BusinessRuleException("Adding a Track", errors); } else { //good to go //commit the Staged work to the database context.SaveChanges(); } } // this ensures that the sql connection closes properly } //eom
}//eom public void Add_TrackToPLaylist(string playlistname, string username, int trackid) { using (var context = new ChinookSystemContext()) { //code to go here //there are 2 default datatypes from Linq given to // the datatype var: IEnumerable or IQueryable //in C# explicit datatypes are created at compile time Playlist exists = (from x in context.Playlists where x.Name.Equals(playlistname) && x.UserName.Equals(username) select x).FirstOrDefault(); // use this to find something if it exists or not PlaylistTrack newTrack = null; int tracknumber = 0; //this list is required for use by the Business Rule exception of the // MessageUserControl List <string> reasons = new List <string>(); // determine if the Playlist ("parent") instance needs to be created if (exists == null) { //create a new playlist exists = new Playlist(); exists.Name = playlistname; exists.UserName = username; //the .Add(item) ONLY stages your record for adding to the database //the actual Physical Add to the database is done on .SaveChanges(); //the returned data instance from the add will happen when the .Savechanges() is // actually executed. //thus there is a logic delay on this code //there is NO Real Identity value in the returned instance //If you return the instance PK value will be 0 exists = context.Playlists.Add(exists); //sence this is a new playlist //logically the track number will be 1 tracknumber = 1; } else { //calculate the next track number for an existing playlist tracknumber = exists.PlaylistTracks.Count() + 1; //restriction (BusinessRule) // BusinessRule requires all error to be in a single List<string> //A track may only exist once in the playlist newTrack = exists.PlaylistTracks.SingleOrDefault(x => x.TrackId == trackid); if (newTrack != null) { reasons.Add("Track already exists on Playlist"); } } // do we add the track to the playlist - reasons list has all the errors so we can check for reasons count if (reasons.Count() > 0) { //some business rule within the trasaction has failed //throw the BusinessRuleException throw new BusinessRuleException("Adding track to playlist", reasons); } else { // Part 2 // Adding the new track to the playlist tracks table // create a new instanrace of the PlaylistTrack newTrack = new PlaylistTrack(); //load with known data newTrack.TrackId = trackid; newTrack.TrackNumber = tracknumber; // currently the Playlist ID is unknown if the Playlist is brand new // NOTE: using navigational properties, one can let the HashSet of // playlist handle the PlaylistId PKey Value. // Adding via the navigational property will have the system enter // the parent PKey for the corresponding FKey value // In PlaylistTrack, PlaylistId is BOTH, the PKey and FKey // During Savechanges() the PlaylistId will be filled exists.PlaylistTracks.Add(newTrack); //committing of your work // only one comit for the transaction // During .Savechanges() the data is added physically to // your database at which time PKey (identity) is generated //the order of actions has been done by your logic // the playlist PKey will be generated //this value will be placed in the FKey of the child record // the child record will be placed in its table context.SaveChanges(); } } }//eom