/// <summary> /// Add the album to the Artist, and if necessary, to the AlbumIds as well. /// </summary> /// <param name="Artist">The Artist</param> /// <param name="Album">The album being added</param> /// <remarks> /// Only add an AlbumId if to the AlbumIds collection if it's not already there. /// It won't be if the its is a New Album being created, but there will be when /// reloading the persisted data. /// </remarks> private void AddAlbumToArtist(Artist Artist, Album Album) { // Add the Album to the albums collection Artist.Albums.Add(Album); // Only add an AlbumId if to the AlbumIds collection if it's not already there. // It won't be if the its is a New Album being created, // but there will be when reloading the persisted data. if (!Artist.AlbumIds.Contains(Album.Id)) Artist.AlbumIds.Add(Album.Id); }
/// <summary> /// Adds a new Artist to the Artists collection and updates the albums referenced /// </summary> /// <param name="UnitOfWork">In-Memory context</param> /// <param name="Artist">the New artist</param> /// <param name="Album">The Album it relates to</param> /// <returns>The New Artist</returns> /// <remarks> /// <para> /// Only add an AlbumId if to the AlbumIds collection if it's not already there. /// It won't be if the its is a New Album being created, but there will be when /// reloading the persisted data. /// </para> /// <para> /// Concurrency: /// </para> /// <Para> /// This routine provides a Monitor lock to ensure that only one instance of this /// can modify the Artists collection at a time. /// It locks from the point which a new Id is generated for the Artist being added /// and retains that until the Artist is added to the Genres collection. /// This type of lock is preferred to ensure the generated Id is updated within /// the Genres collection before any other thread can try and Add a Genre which /// would require the Id for this one, which woudl be used in the GenerateId /// methods. This is to avoid duplicate Id's being generated. /// </Para> /// <para> /// This is a very course grained way of locking but is acceptible within this /// application as it is a Windows 8 store app, and not subjected to multiple /// users, only the individual threads within the application. The performance /// hit should not be that noticable here. /// </para> /// </remarks> private Artist AddArtist(IUnitOfWork UnitOfWork, Artist Artist, Album Album) { // lock (_ArtistLock) { // Concurrency: Lock between getting the Id and performing the update, as the // this new Id won't be availble for checking purposes by another // thread that is looking to add an Artist. This should avoid the // possiblilties of duplicate Id's Artist.Albums = new List<Album>(); // i. Generate ArtistId, if there isn'[t one already, will be reloading persisted data. if (Artist.Id == 0) Artist.Id = GenerateArtistId(UnitOfWork); // ii. Add album ref to Artist AddAlbumToArtist(Artist, Album); // iii.Add Artist to Artists Collection UnitOfWork.Artists.Add(Artist); } return Artist; }
/// <summary> /// Updates the Artist in the Artists collection. /// </summary> /// <param name="UnitOfWork">The In-Memory context</param> /// <param name="Artist">The artist to be updated</param> /// <param name="Album">The album</param> /// <returns>The Updated Artist</returns> /// <remarks> /// The update artist is returned so that it can replace the /// Artist in the album, which means the navigation properties /// are up to date. /// <para> /// Concurrency: /// </para> /// <Para> /// This routine provides a Monitor lock to ensure that only one instance of this /// can modify the Artists collection at a time. /// It locks from the point where the Genre to be updated is retrieved from /// the Artist /// and retains that until the Artist is updated in the Artists collection. /// This type of lock is preferred to ensure that no other updates to the Artist /// are possible while this update occurs. /// </Para> /// <para> /// This is a very course grained way of locking but is acceptible within this /// application as it is a Windows 8 store app, and not subjected to multiple /// users, only the individual threads within the application. The performance /// hit should not be that noticable here. /// </para> /// </remarks> private Artist UpdateArtist(IUnitOfWork UnitOfWork, Artist Artist, Album Album) { int idx = 0; lock (_ArtistLock) { // Get the index of the Artist idx = UnitOfWork.Artists.FindIndex(a => a.Name == Artist.Name); // Get the Artist var updatedArtist = UnitOfWork.Artists[idx]; // If Album exists in the retrieved Artist. var al = updatedArtist.Albums.FirstOrDefault(a => a.Id == Album.Id); if (al != null) { // The Album is found, so replace it var alIdx = updatedArtist.Albums.IndexOf(al); updatedArtist.Albums[alIdx] = Album; } else { // Album dosn't exist in the Artist.Albums collection, so just add it. AddAlbumToArtist(updatedArtist, Album); } // Replace the Artist in the Artists collection UnitOfWork.Artists[idx] = updatedArtist; } // return the updated Artist return UnitOfWork.Artists[idx]; // return updatedArtist; }
/// <summary> /// Add the Artist to the In-Memory context. The updated /// Artist is returned to update the Album /// </summary> /// <param name="UnitOfWork">In-Memory context</param> /// <param name="Artist">The Artist to be updated</param> /// <param name="Album">The album reference</param> /// <returns>The updated Artist</returns> /// <remarks> /// <para> /// Only add an AlbumId if to the AlbumIds collection if it's not already there. /// It won't be if the its is a New Album being created, but there will be when /// reloading the persisted data. /// </para> /// </remarks> public Artist AddArtistToContext(IUnitOfWork UnitOfWork, Artist Artist, Album Album) { // 4a If exists, Add album reference to the Artist if (ArtistExists(UnitOfWork, Artist.Name)) { var updatedArtist = UpdateArtist(UnitOfWork, Artist, Album); return updatedArtist; } else { // 4b If doesn't exist, generate Artist Id var newArtist = AddArtist(UnitOfWork, Artist, Album); // iv. Replace Artist to Album.Artist return Artist; } }