diff --git a/Management/src/AspDotNetCore/CloudFoundry/git.properties b/Management/src/AspDotNetCore/CloudFoundry/git.properties index ca658ff1..2b44045f 100644 --- a/Management/src/AspDotNetCore/CloudFoundry/git.properties +++ b/Management/src/AspDotNetCore/CloudFoundry/git.properties @@ -1,9 +1,9 @@ -git.remote.origin.url=C:/steeltoe/samples +git.remote.origin.url=c:/workspace/Samples git.build.version=1.1.0 -git.commit.id.abbrev=61c1bf0 -git.commit.id=61c1bf09d9be5c2070e5ac34d19082df6ad8f7a1 +git.commit.id.abbrev=4de1ee6 +git.commit.id=4de1ee655e9af6119941d9157fdedf89d40af542 git.tags= git.branch=dev -git.build.time=2017-11-14T12:28:20.1143122-06:00 -git.build.user.name=Tim -git.build.host=DESKTOP-41EUE34 +git.build.time=2017-12-05T13:02:20.8914239-08:00 +git.build.user.name=dtillman +git.build.host=DESKTOP-D0GL5GA diff --git a/MusicStore/createCloudFoundryServices.cmd b/MusicStore/createCloudFoundryServices.cmd index e8845cd6..a4572fbf 100644 --- a/MusicStore/createCloudFoundryServices.cmd +++ b/MusicStore/createCloudFoundryServices.cmd @@ -5,7 +5,8 @@ SET db_plan=100mb IF NOT "%1"=="" set db_service=%1 IF NOT "%2"=="" set db_plan=%2 cf create-service p-config-server standard mStoreConfig -c config-server.json -cf create-service p-service-registry standard mStoreRegistry +cf create-service p-service-registry standard mStoreRegistry +cf create-service p-circuit-breaker-dashboard standard mStoreHystrix cf create-service %db_service% %db_plan% mStoreAccountsDB cf create-service %db_service% %db_plan% mStoreOrdersDB cf create-service %db_service% %db_plan% mStoreCartDB diff --git a/MusicStore/createCloudFoundryServices.sh b/MusicStore/createCloudFoundryServices.sh index 45e7fd89..f0a6e4b1 100755 --- a/MusicStore/createCloudFoundryServices.sh +++ b/MusicStore/createCloudFoundryServices.sh @@ -13,7 +13,7 @@ if [ "$2" != "" ]; then db_plan=$2 fi - +cf create-service p-circuit-breaker-dashboard standard mStoreHystrix cf create-service p-config-server standard mStoreConfig -c config-server.json cf create-service p-service-registry standard mStoreRegistry cf create-service "$db_service" "$db_plan" mStoreAccountsDB @@ -21,6 +21,7 @@ cf create-service "$db_service" "$db_plan" mStoreOrdersDB cf create-service "$db_service" "$db_plan" mStoreCartDB cf create-service "$db_service" "$db_plan" mStoreStoreDB + svc_count=6 if [ "$USE_REDIS_CACHE" != "" ]; then cf create-service p-redis shared-vm mStoreRedis diff --git a/MusicStore/deleteCloudFoundryServices.cmd b/MusicStore/deleteCloudFoundryServices.cmd index 2e595e9a..8e6ad8c7 100644 --- a/MusicStore/deleteCloudFoundryServices.cmd +++ b/MusicStore/deleteCloudFoundryServices.cmd @@ -6,4 +6,5 @@ cf delete-service mStoreAccountsDB cf delete-service mStoreOrdersDB cf delete-service mStoreCartDB cf delete-service mStoreStoreDB -cf delete-service mStoreRedis \ No newline at end of file +cf delete-service mStoreRedis +cf delete-service mStoreHystrix \ No newline at end of file diff --git a/MusicStore/deleteCloudFoundryServices.sh b/MusicStore/deleteCloudFoundryServices.sh index 0e2e51d9..d0afe574 100644 --- a/MusicStore/deleteCloudFoundryServices.sh +++ b/MusicStore/deleteCloudFoundryServices.sh @@ -6,4 +6,5 @@ cf delete-service mStoreAccountsDB cf delete-service mStoreOrdersDB cf delete-service mStoreCartDB cf delete-service mStoreStoreDB -cf delete-service mStoreRedis \ No newline at end of file +cf delete-service mStoreRedis +cf delete-service mStoreHystrix \ No newline at end of file diff --git a/MusicStore/pushMusicStoreService.cmd b/MusicStore/pushMusicStoreService.cmd index 89d3da53..310d2a68 100644 --- a/MusicStore/pushMusicStoreService.cmd +++ b/MusicStore/pushMusicStoreService.cmd @@ -3,11 +3,10 @@ IF "%1"=="" GOTO :usage IF "%2"=="" GOTO :usage SET r=%1 cd src\MusicStoreService -IF EXIST %TEMP%\publish (CMD /C "RMDIR /q /s %TEMP%\publish") dotnet restore -dotnet publish --output %TEMP%\publish --configuration Release --runtime %1 --framework %2 -IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p %TEMP%\publish") -IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p %TEMP%\publish") +dotnet publish --configuration Release --runtime %1 --framework %2 +IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p bin\Release\%2\%1\publish") +IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p bin\Release\%2\%1\publish") cd ..\.. exit /b :usage diff --git a/MusicStore/pushMusicStoreService.sh b/MusicStore/pushMusicStoreService.sh index d40fbd80..f69f1c01 100755 --- a/MusicStore/pushMusicStoreService.sh +++ b/MusicStore/pushMusicStoreService.sh @@ -16,15 +16,13 @@ if [ "$2" == "" ]; then fi r=$1 cd src/MusicStoreService -if [ -d "$TMPDIR/publish" ]; then - rm -rf "$TMPDIR/publish" -fi + dotnet restore --configfile nuget.config -dotnet publish --output $TMPDIR/publish --configuration Release --runtime "$1" --framework "$2" +dotnet publish --configuration Release --runtime "$1" --framework "$2" if [ "${r:0:3}" == "win" ]; then - cf push -f manifest-windows.yml -p "$TMPDIR/publish" + cf push -f manifest-windows.yml -p "bin/Release/$2/$1/publish" fi if [ "${r:0:6}" == "ubuntu" ]; then - cf push -f manifest.yml -p "$TMPDIR/publish" + cf push -f manifest.yml -p "bin/Release/$2/$1/publish" fi cd ../.. \ No newline at end of file diff --git a/MusicStore/pushMusicStoreUI.cmd b/MusicStore/pushMusicStoreUI.cmd index 0cccdca0..c8908868 100644 --- a/MusicStore/pushMusicStoreUI.cmd +++ b/MusicStore/pushMusicStoreUI.cmd @@ -3,20 +3,20 @@ IF "%1"=="" GOTO :usage IF "%2"=="" GOTO :usage SET r=%1 cd src\MusicStoreUI -IF EXIST %TEMP%\publish (CMD /C "RMDIR /q /s %TEMP%\publish") +IF NOT "%USE_REDIS_CACHE%"=="" (set DefineConstants=USE_REDIS_CACHE) set winmanifest=manifest-windows.yml IF NOT "%USE_REDIS_CACHE%"=="" (set winmanifest=manifest-windows-redis.yml) set nixmanifest=manifest.yml IF NOT "%USE_REDIS_CACHE%"=="" (set nixmanifest=manifest-redis.yml) dotnet restore -dotnet publish --output %TEMP%\publish --configuration Release --runtime %1 --framework %2 -IF "%r:~0,3%"=="win" (CMD /c "cf push -f %winmanifest% -p %TEMP%\publish") -IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f %nixmanifest% -p %TEMP%\publish") +dotnet publish --configuration Release --runtime %1 --framework %2 +IF "%r:~0,3%"=="win" (CMD /c "cf push -f %winmanifest% -p bin\Release\%2\%1\publish") +IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f %nixmanifest% -p bin\Release\%2\%1\publish") cd ..\.. exit /b :usage echo USAGE: echo pushMusicStoreUI [runtime] [framework] echo runtime - target runtime to publish (e.g. win10-x64, ubuntu.14.04-x64) -echo framework - target framework to publish (e.g. net461, netcoreapp1.1) +echo framework - target framework to publish (e.g. net461, netcoreapp2.0) exit /b \ No newline at end of file diff --git a/MusicStore/pushMusicStoreUI.sh b/MusicStore/pushMusicStoreUI.sh index 711371b7..183f59be 100755 --- a/MusicStore/pushMusicStoreUI.sh +++ b/MusicStore/pushMusicStoreUI.sh @@ -4,7 +4,7 @@ function printUsage() echo "USAGE:" echo "pushMusicStoreUI [runtime] [framework]" echo "runtime - target runtime to publish (e.g. win10-x64, ubuntu.14.04-x64)" -echo "framework - target framework to publish (e.g. net461, netcoreapp1.1)" +echo "framework - target framework to publish (e.g. net461, netcoreapp2.0)" exit } # @@ -21,16 +21,13 @@ if [ "$USE_REDIS_CACHE" == "true" ]; then nixmanifest=manifest-redis.yml winmanifest=manifest-windows-redis.yml fi -cd src/MusicStoreUI -if [ -d "$TMPDIR/publish" ]; then - rm -rf "$TMPDIR/publish" -fi + dotnet restore --configfile nuget.config -dotnet publish --output $TMPDIR/publish --configuration Release --runtime "$1" --framework "$2" +dotnet publish --configuration Release --runtime "$1" --framework "$2" if [ "${r:0:3}" == "win" ]; then - cf push -f "$winmanifest" -p "$TMPDIR/publish" + cf push -f "$winmanifest" -p "bin/Release/$2/$1/publish" fi if [ "${r:0:6}" == "ubuntu" ]; then - cf push -f "$nixmanifest" -p "$TMPDIR/publish" + cf push -f "$nixmanifest" -p "bin/Release/$2/$1/publish" fi cd ../.. diff --git a/MusicStore/pushOrderService.cmd b/MusicStore/pushOrderService.cmd index 0e073634..f5468557 100644 --- a/MusicStore/pushOrderService.cmd +++ b/MusicStore/pushOrderService.cmd @@ -3,11 +3,10 @@ IF "%1"=="" GOTO :usage IF "%2"=="" GOTO :usage SET r=%1 cd src\OrderService -IF EXIST %TEMP%\publish (CMD /C "RMDIR /q /s %TEMP%\publish") dotnet restore -dotnet publish --output %TEMP%\publish --configuration Release --runtime %1 --framework %2 -IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p %TEMP%\publish") -IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p %TEMP%\publish") +dotnet publish --configuration Release --runtime %1 --framework %2 +IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p bin\Release\%2\%1\publish") +IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p bin\Release\%2\%1\publish") cd ..\.. exit /b :usage diff --git a/MusicStore/pushOrderService.sh b/MusicStore/pushOrderService.sh index 86814b3c..124e058b 100755 --- a/MusicStore/pushOrderService.sh +++ b/MusicStore/pushOrderService.sh @@ -16,15 +16,13 @@ if [ "$2" == "" ]; then fi r=$1 cd src/OrderService -if [ -d "$TMPDIR/publish" ]; then - rm -rf "$TMPDIR/publish" -fi + dotnet restore --configfile nuget.config -dotnet publish --output $TMPDIR/publish --configuration Release --runtime "$1" --framework "$2" +dotnet publish --configuration Release --runtime "$1" --framework "$2" if [ "${r:0:3}" == "win" ]; then - cf push -f manifest-windows.yml -p "$TMPDIR/publish" + cf push -f manifest-windows.yml -p "bin/Release/$2/$1/publish" fi if [ "${r:0:6}" == "ubuntu" ]; then - cf push -f manifest.yml -p "$TMPDIR/publish" + cf push -f manifest.yml -p "bin/Release/$2/$1/publish" fi cd ../.. \ No newline at end of file diff --git a/MusicStore/pushShoppingCartService.cmd b/MusicStore/pushShoppingCartService.cmd index 0431a542..5b15ec76 100644 --- a/MusicStore/pushShoppingCartService.cmd +++ b/MusicStore/pushShoppingCartService.cmd @@ -3,11 +3,10 @@ IF "%1"=="" GOTO :usage IF "%2"=="" GOTO :usage SET r=%1 cd src\ShoppingCartService -IF EXIST %TEMP%\publish (CMD /C "RMDIR /q /s %TEMP%\publish") dotnet restore -dotnet publish --output %TEMP%\publish --configuration Release --runtime %1 --framework %2 -IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p %TEMP%\publish") -IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p %TEMP%\publish") +dotnet publish --configuration Release --runtime %1 --framework %2 +IF "%r:~0,3%"=="win" (CMD /c "cf push -f manifest-windows.yml -p bin\Release\%2\%1\publish") +IF "%r:~0,6%"=="ubuntu" (CMD /c "cf push -f manifest.yml -p bin\Release\%2\%1\publish") cd ..\.. exit /b :usage diff --git a/MusicStore/pushShoppingCartService.sh b/MusicStore/pushShoppingCartService.sh index 1b6bedc3..f232cadc 100755 --- a/MusicStore/pushShoppingCartService.sh +++ b/MusicStore/pushShoppingCartService.sh @@ -16,15 +16,13 @@ if [ "$2" == "" ]; then fi r=$1 cd src/ShoppingCartService -if [ -d "$TMPDIR/publish" ]; then - rm -rf "$TMPDIR/publish" -fi + dotnet restore --configfile nuget.config -dotnet publish --output $TMPDIR/publish --configuration Release --runtime "$1" --framework "$2" +dotnet publish --configuration Release --runtime "$1" --framework "$2" if [ "${r:0:3}" == "win" ]; then - cf push -f manifest-windows.yml -p "$TMPDIR/publish" + cf push -f manifest-windows.yml -p "bin/Release/$2/$1/publish" fi if [ "${r:0:6}" == "ubuntu" ]; then - cf push -f manifest.yml -p "$TMPDIR/publish" + cf push -f manifest.yml -p "bin/Release/$2/$1/publish" fi cd ../.. \ No newline at end of file diff --git a/MusicStore/src/MusicStoreService/Controllers/StoreController.cs b/MusicStore/src/MusicStoreService/Controllers/StoreController.cs index e9f7464d..cd6bab99 100644 --- a/MusicStore/src/MusicStoreService/Controllers/StoreController.cs +++ b/MusicStore/src/MusicStoreService/Controllers/StoreController.cs @@ -8,6 +8,7 @@ using MusicStore.Models; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; +using Microsoft.Extensions.Logging; namespace MusicStore.Controllers { @@ -15,11 +16,12 @@ namespace MusicStore.Controllers public class StoreController : Controller { private readonly AppSettings _appSettings; - - public StoreController(MusicStoreContext dbContext, IOptions options) + private readonly ILogger _logger; + public StoreController(MusicStoreContext dbContext, IOptions options, ILogger logger) { DbContext = dbContext; _appSettings = options.Value; + _logger = logger; } public MusicStoreContext DbContext { get; } @@ -29,6 +31,8 @@ namespace MusicStore.Controllers [HttpGet("Genres")] public async Task> GetGenres() { + _logger.LogDebug("GetGenres"); + var genres = await DbContext.Genres .Include(g => g.Albums) .ToListAsync(); @@ -41,6 +45,7 @@ namespace MusicStore.Controllers public async Task GetGenre( [FromQuery] int? id, [FromQuery] string name) { + _logger.LogDebug("GetGenre"); Genre genre = null; if (id.HasValue) { @@ -71,6 +76,7 @@ namespace MusicStore.Controllers [HttpGet("Albums")] public async Task GetAlbums([FromQuery] string genre) { + _logger.LogDebug("GetAlbums"); // Retrieve Genre genre and its Associated associated Albums albums from database List albums = null; @@ -119,6 +125,8 @@ namespace MusicStore.Controllers public async Task GetAlbum( [FromQuery] int? id, [FromQuery] string title) { + _logger.LogDebug("GetAlbum"); + Album album = null; if (id.HasValue) { @@ -148,6 +156,7 @@ namespace MusicStore.Controllers // public async Task> GetTopSelling([FromQuery] int count = 6) public List GetTopSelling([FromQuery] int count = 6) { + _logger.LogDebug("GetTopSelling"); // TODO: Current MySQL provider has a Take() bug // See: http://forums.mysql.com/read.php?38,650020,650020#msg-650020 @@ -182,6 +191,7 @@ namespace MusicStore.Controllers [HttpGet("Artists")] public async Task> GetArtists() { + _logger.LogDebug("GetArtists"); var artists = await DbContext.Artists.ToListAsync(); return ArtistJson.From(artists); } @@ -192,6 +202,7 @@ namespace MusicStore.Controllers public async Task GetArtist( [FromQuery] int id) { + _logger.LogDebug("GetArtist"); Artist artist = await DbContext.Artists .Where(a => a.ArtistId == id) .FirstOrDefaultAsync(); @@ -211,6 +222,7 @@ namespace MusicStore.Controllers [HttpPost("Album/")] public async Task AddAlbum([FromBody] AlbumJson json) { + _logger.LogDebug("AddAlbum"); if (json == null) { return BadRequest(); @@ -245,6 +257,8 @@ namespace MusicStore.Controllers [HttpPut("Album/")] public async Task UpdateAlbum([FromBody] AlbumJson json) { + _logger.LogDebug("UpdateAlbum"); + if (json == null) { return BadRequest(); @@ -307,6 +321,8 @@ namespace MusicStore.Controllers [HttpDelete("Album/{id}")] public async Task DeleteAlbum(int id) { + _logger.LogDebug("DeleteAlbum"); + Album album = await DbContext.Albums .Where(a => a.AlbumId == id) .FirstOrDefaultAsync(); diff --git a/MusicStore/src/MusicStoreService/MusicStoreService.csproj b/MusicStore/src/MusicStoreService/MusicStoreService.csproj index dc22c08c..06ebc543 100755 --- a/MusicStore/src/MusicStoreService/MusicStoreService.csproj +++ b/MusicStore/src/MusicStoreService/MusicStoreService.csproj @@ -19,12 +19,15 @@ - + - + + + + + - - + diff --git a/MusicStore/src/MusicStoreService/Startup.cs b/MusicStore/src/MusicStoreService/Startup.cs index 2f4c31bc..4069c9ff 100644 --- a/MusicStore/src/MusicStoreService/Startup.cs +++ b/MusicStore/src/MusicStoreService/Startup.cs @@ -26,24 +26,28 @@ namespace MusicStore // Add custom health check contributor services.AddSingleton(); - // Add managment endpoint services + // Add Steeltoe Management services services.AddCloudFoundryActuators(Configuration); // Add framework services. services.Configure(Configuration.GetSection("AppSettings")); - services.AddMvc(); - + // Steeltoe Service Discovery services.AddDiscoveryClient(Configuration); + // Steeltoe MySQL Connector services.AddDbContext(options => options.UseMySql(Configuration)); + + // Add Framework services + services.AddMvc(); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - // Add management endpoints into pipeline + // Add Steeltoe Management endpoints into pipeline app.UseCloudFoundryActuators(); app.UseMvc(routes => @@ -58,6 +62,7 @@ namespace MusicStore template: "{controller}/{id?}"); }); + // Start Steeltoe Discovery services app.UseDiscoveryClient(); } } diff --git a/MusicStore/src/MusicStoreUI/Areas/Admin/Controllers/StoreManagerController.cs b/MusicStore/src/MusicStoreUI/Areas/Admin/Controllers/StoreManagerController.cs index 7408b8fa..a2e326b7 100644 --- a/MusicStore/src/MusicStoreUI/Areas/Admin/Controllers/StoreManagerController.cs +++ b/MusicStore/src/MusicStoreUI/Areas/Admin/Controllers/StoreManagerController.cs @@ -1,3 +1,7 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; @@ -5,13 +9,9 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using MusicStoreUI.Models; -using MusicStoreUI.Services; -using MusicStoreUI.Services.HystrixCommands; using MusicStoreUI.ViewModels; -using Steeltoe.CircuitBreaker.Hystrix; -using System; -using System.Threading; -using System.Threading.Tasks; +using MusicStoreUI.Services; +using System.Collections.Generic; namespace MusicStoreUI.Areas.Admin.Controllers { @@ -21,15 +21,11 @@ namespace MusicStoreUI.Areas.Admin.Controllers { private readonly AppSettings _appSettings; private readonly IMusicStore MusicStoreService; - private GenresCommand _genres; - private ArtistsAllCommand _artists; public StoreManagerController(IMusicStore musicStore, IOptions options) { MusicStoreService = musicStore; _appSettings = options.Value; - _genres = new GenresCommand(HystrixCommandGroupKeyDefault.AsKey("MusicStoreGenres"), MusicStoreService); - _artists = new ArtistsAllCommand("MuscStoreArtists", MusicStoreService); } @@ -37,9 +33,14 @@ namespace MusicStoreUI.Areas.Admin.Controllers // GET: /StoreManager/ public async Task Index() { - var albumsCommand = new AlbumsAllCommand("GetAlbum", MusicStoreService); - var albums = await albumsCommand.ExecuteAsync(); - return View(albums); + try + { + var albums = await MusicStoreService.GetAllAlbumsAsync(); + return View(albums); + } catch + { + return View(new List()); + } } // @@ -50,12 +51,12 @@ namespace MusicStoreUI.Areas.Admin.Controllers { var cacheKey = GetCacheKey(id); - if (!cache.TryGetValue(cacheKey, out Album album)) + Album album; + if (!cache.TryGetValue(cacheKey, out album)) { - var albumCommand = new AlbumCommand("GetAlbum", MusicStoreService, id); - album = await albumCommand.ExecuteAsync(); + album = await MusicStoreService.GetAlbumAsync(id); - if (album != null && !albumCommand.IsResponseFromFallback) + if (album != null) { if (_appSettings.CacheDbResults) { @@ -81,8 +82,8 @@ namespace MusicStoreUI.Areas.Admin.Controllers // GET: /StoreManager/Create public async Task Create() { - var genres = await _genres.ExecuteAsync(); - var artists = await _artists.ExecuteAsync(); + var genres = await MusicStoreService.GetGenresAsync(); + var artists = await MusicStoreService.GetAllArtistsAsync(); ViewBag.GenreId = new SelectList(genres, "GenreId", "Name"); ViewBag.ArtistId = new SelectList(artists, "ArtistId", "Name"); @@ -92,17 +93,18 @@ namespace MusicStoreUI.Areas.Admin.Controllers // POST: /StoreManager/Create [HttpPost] [ValidateAntiForgeryToken] - public async Task Create(Album album, [FromServices] IMemoryCache cache, CancellationToken requestAborted) + public async Task Create( + Album album, + [FromServices] IMemoryCache cache, + CancellationToken requestAborted) { if (ModelState.IsValid) { album.Artist = await MusicStoreService.GetArtistAsync(album.ArtistId); - - var genreCommand = new GenreCommand("MusicStoreGenre", MusicStoreService, album.GenreId); - album.Genre = await genreCommand.ExecuteAsync(); + album.Genre = await MusicStoreService.GetGenreAsync(album.GenreId); await MusicStoreService.AddAlbumAsync(album); - + var albumData = new AlbumData { @@ -117,8 +119,8 @@ namespace MusicStoreUI.Areas.Admin.Controllers return RedirectToAction("Index"); } - var genres = await _genres.ExecuteAsync(); - var artists = await _artists.ExecuteAsync(); + var genres = await MusicStoreService.GetGenresAsync(); + var artists = await MusicStoreService.GetAllArtistsAsync(); ViewBag.GenreId = new SelectList(genres, "GenreId", "Name", album.GenreId); ViewBag.ArtistId = new SelectList(artists, "ArtistId", "Name", album.ArtistId); @@ -135,8 +137,8 @@ namespace MusicStoreUI.Areas.Admin.Controllers { return NotFound(); } - var genres = await _genres.ExecuteAsync(); - var artists = await _artists.ExecuteAsync(); + var genres = await MusicStoreService.GetGenresAsync(); + var artists = await MusicStoreService.GetAllArtistsAsync(); ViewBag.GenreId = new SelectList(genres, "GenreId", "Name", album.GenreId); ViewBag.ArtistId = new SelectList(artists, "ArtistId", "Name", album.ArtistId); @@ -147,21 +149,23 @@ namespace MusicStoreUI.Areas.Admin.Controllers // POST: /StoreManager/Edit/5 [HttpPost] [ValidateAntiForgeryToken] - public async Task Edit([FromServices] IMemoryCache cache, Album album, CancellationToken requestAborted) + public async Task Edit( + [FromServices] IMemoryCache cache, + Album album, + CancellationToken requestAborted) { if (ModelState.IsValid) { album.Artist = await MusicStoreService.GetArtistAsync(album.ArtistId); - var genreCommand = new GenreCommand("MusicStoreGenre", MusicStoreService, album.GenreId); - album.Genre = await genreCommand.ExecuteAsync(); + album.Genre = await MusicStoreService.GetGenreAsync(album.GenreId); await MusicStoreService.UpdateAlbumAsync(album); //Invalidate the cache entry as it is modified cache.Remove(GetCacheKey(album.AlbumId)); return RedirectToAction("Index"); } - var genres = await _genres.ExecuteAsync(); - var artists = await _artists.ExecuteAsync(); + var genres = await MusicStoreService.GetGenresAsync(); + var artists = await MusicStoreService.GetAllArtistsAsync(); ViewBag.GenreId = new SelectList(genres, "GenreId", "Name", album.GenreId); ViewBag.ArtistId = new SelectList(artists, "ArtistId", "Name", album.ArtistId); @@ -172,8 +176,7 @@ namespace MusicStoreUI.Areas.Admin.Controllers // GET: /StoreManager/RemoveAlbum/5 public async Task RemoveAlbum(int id) { - var albumCommand = new AlbumCommand("GetAlbum", MusicStoreService, id); - var album = await albumCommand.ExecuteAsync(); + var album = await MusicStoreService.GetAlbumAsync(id); if (album == null) { return NotFound(); @@ -218,8 +221,7 @@ namespace MusicStoreUI.Areas.Admin.Controllers [EnableCors("CorsPolicy")] public async Task GetAlbumIdFromName(string albumName) { - var albumCommand = new AlbumCommand("GetAlbum", MusicStoreService, albumName); - var album = await albumCommand.ExecuteAsync(); + var album = await MusicStoreService.GetAlbumAsync(albumName); if (album == null) { diff --git a/MusicStore/src/MusicStoreUI/Components/GenreMenuComponent.cs b/MusicStore/src/MusicStoreUI/Components/GenreMenuComponent.cs index d64f65dc..f1b5ac04 100644 --- a/MusicStore/src/MusicStoreUI/Components/GenreMenuComponent.cs +++ b/MusicStore/src/MusicStoreUI/Components/GenreMenuComponent.cs @@ -3,26 +3,26 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using MusicStoreUI.Services; using MusicStoreUI.Services.HystrixCommands; -using Steeltoe.CircuitBreaker.Hystrix; +using Models = MusicStoreUI.Models; +using System.Collections.Generic; namespace MusicStoreUI.Components { [ViewComponent(Name = "GenreMenu")] public class GenreMenuComponent : ViewComponent { - private GenresCommand _genres; + private GetGenres _genres; - public GenreMenuComponent(IMusicStore musicStore) + public GenreMenuComponent(GetGenres genres) { - MusicStore = musicStore; - _genres = new GenresCommand(HystrixCommandGroupKeyDefault.AsKey("MusicStoreGenres"), musicStore); + _genres = genres; } private IMusicStore MusicStore { get; } public async Task InvokeAsync() { - var genres = await _genres.ExecuteAsync(); + List genres = await _genres.GetGenresAsync(); return View(genres.Select(g => g.Name).Take(9).ToList()); } } diff --git a/MusicStore/src/MusicStoreUI/Controllers/HomeController.cs b/MusicStore/src/MusicStoreUI/Controllers/HomeController.cs index 04fe017a..c6db298d 100644 --- a/MusicStore/src/MusicStoreUI/Controllers/HomeController.cs +++ b/MusicStore/src/MusicStoreUI/Controllers/HomeController.cs @@ -3,9 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Options; -using MusicStoreUI.Models; +using Model =MusicStoreUI.Models; using MusicStoreUI.Services; using MusicStoreUI.Services.HystrixCommands; @@ -13,41 +11,16 @@ namespace MusicStoreUI.Controllers { public class HomeController : Controller { - private readonly AppSettings _appSettings; - - public HomeController(IOptions options ) + public HomeController() { - _appSettings = options.Value; } // GET: /Home/ public async Task Index( - [FromServices] IMusicStore musicStore, - [FromServices] IMemoryCache cache) + [FromServices] GetTopAlbums topAlbumsCommand + ) { - // Get most popular albums - var cacheKey = "topselling"; - if (!cache.TryGetValue(cacheKey, out List albums)) - { - var albumCommand = new AlbumsTopCommand("TopAlbums", musicStore, 6); - albums = await albumCommand.ExecuteAsync(); - - if (albums != null && albums.Count > 0 && !albumCommand.IsResponseFromFallback) - { - if (_appSettings.CacheDbResults) - { - // Refresh it every 10 minutes. - // Let this be the last item to be removed by cache if cache GC kicks in. - cache.Set( - cacheKey, - albums, - new MemoryCacheEntryOptions() - .SetAbsoluteExpiration(TimeSpan.FromMinutes(10)) - .SetPriority(CacheItemPriority.High)); - } - } - } - + List albums = await topAlbumsCommand.GetTopSellingAlbumsAsync(6); return View(albums); } diff --git a/MusicStore/src/MusicStoreUI/Controllers/ShoppingCartController.cs b/MusicStore/src/MusicStoreUI/Controllers/ShoppingCartController.cs index f8e7219f..c4cfb518 100644 --- a/MusicStore/src/MusicStoreUI/Controllers/ShoppingCartController.cs +++ b/MusicStore/src/MusicStoreUI/Controllers/ShoppingCartController.cs @@ -7,6 +7,7 @@ using MusicStoreUI.ViewModels; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Command = MusicStoreUI.Services.HystrixCommands; namespace MusicStoreUI.Controllers { @@ -44,11 +45,14 @@ namespace MusicStoreUI.Controllers // // GET: /ShoppingCart/AddToCart/5 - public async Task AddToCart(int id, CancellationToken requestAborted) + public async Task AddToCart( + [FromServices] Command.GetAlbum albumCommand, + int id, + CancellationToken requestAborted) { // Retrieve the album from the database - var albumCommand = new AlbumCommand("GetAlbum", MusicStoreService, id); - var addedAlbum = await albumCommand.ExecuteAsync(); + + var addedAlbum = await albumCommand.GetAlbumAsync(id); // Add it to the shopping cart var cart = ShoppingCart.GetCart(ShoppingCartService, MusicStoreService, null, HttpContext); diff --git a/MusicStore/src/MusicStoreUI/Controllers/StoreController.cs b/MusicStore/src/MusicStoreUI/Controllers/StoreController.cs index dcb00538..dc10aad0 100644 --- a/MusicStore/src/MusicStoreUI/Controllers/StoreController.cs +++ b/MusicStore/src/MusicStoreUI/Controllers/StoreController.cs @@ -13,30 +13,31 @@ namespace MusicStoreUI.Controllers public class StoreController : Controller { private readonly AppSettings _appSettings; - private GenresCommand _genres; + private GetGenres _genres; - public StoreController(IMusicStore musicStore, IOptions options) + public StoreController(GetGenres genres, IOptions options) { - MusicStore = musicStore; _appSettings = options.Value; - _genres = new GenresCommand(HystrixCommandGroupKeyDefault.AsKey("MusicStoreGenres"), musicStore); + _genres = genres; } - public IMusicStore MusicStore { get; } // GET: /Store/ public async Task Index() { - var genres = await _genres.ExecuteAsync(); + var genres = await _genres.GetGenresAsync(); return View(genres); } // GET: /Store/Browse?genre=Disco - public async Task Browse(string genre) + public async Task Browse( + [FromServices] Services.HystrixCommands.GetGenre genreCommand, + string genre + ) { - var genreCommand = new GenreCommand("MusicStoreGenre", MusicStore, genre); - var genreModel = await genreCommand.ExecuteAsync(); + + var genreModel = await genreCommand.GetGenreAsync(genre); if (genreModel == null) { @@ -46,32 +47,11 @@ namespace MusicStoreUI.Controllers return View(genreModel); } - public async Task Details([FromServices] IMemoryCache cache, int id) + public async Task Details( + [FromServices] Services.HystrixCommands.GetAlbum albumCommand, + int id) { - var cacheKey = string.Format("album_{0}", id); - if (!cache.TryGetValue(cacheKey, out Album album)) - { - var albumCommand = new AlbumCommand("GetAlbum", MusicStore, id); - album = await albumCommand.ExecuteAsync(); - - if (album != null && !albumCommand.IsResponseFromFallback) - { - if (_appSettings.CacheDbResults) - { - //Remove it from cache if not retrieved in last 10 minutes - cache.Set( - cacheKey, - album, - new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(10))); - } - } - } - - if (album == null) - { - return NotFound(); - } - + var album = await albumCommand.GetAlbumAsync(id); return View(album); } } diff --git a/MusicStore/src/MusicStoreUI/Models/SampleData.cs b/MusicStore/src/MusicStoreUI/Models/SampleData.cs index 692a415c..17cc1efa 100644 --- a/MusicStore/src/MusicStoreUI/Models/SampleData.cs +++ b/MusicStore/src/MusicStoreUI/Models/SampleData.cs @@ -3,7 +3,8 @@ using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; - +using System.Collections.Generic; +using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -27,6 +28,8 @@ namespace MusicStoreUI.Models CreateAdminUser(serviceProvider, configuration).Wait(); } } + + BuildFallbackData(); } private static async Task CreateAdminUser(IServiceProvider serviceProvider, IConfiguration configuration) @@ -80,6 +83,916 @@ namespace MusicStoreUI.Models return true; } + const string imgUrl = "~/Images/placeholder.png"; + public static string ImageUrl { get { return imgUrl; } } + private static Album[] GetAlbums() + { + var genres = Genres; + var artists = Artists; + int id = 99990; + + var albums = new Album[] + { + new Album { AlbumId = ++id, Title = "The Best Of The Men At Work", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Men At Work"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "...And Justice For All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + //new Album { AlbumId = ++id, Title = "עד גבול האור", Genre = genres["World"], Price = 8.99M, Artist = artists["אריק אינשטיין"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Black Light Syndrome", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Terry Bozzio, Tony Levin & Steve Stevens"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "10,000 Days", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "11i", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Supreme Beings of Leisure"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "1960", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Soul-Junk"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "4x4=12 ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Copland Celebration, Vol. I", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Lively Mind", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Matter of Life and Death", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Real Dead One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Real Live One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Rush of Blood to the Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Soprano Inspired", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Britten Sinfonia, Ivor Bolton & Lesley Garrett"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A Winter Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Abbey Road", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ace Of Spades", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Motörhead"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Achtung Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Acústico MTV", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Adams, John: The Chairman Dances", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Edo de Waart & San Francisco Symphony"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Adrenaline", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ænima", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Afrociberdelia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "After the Goldrush", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Neil Young"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Airdrawn Dagger", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Sasha"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Album AlbumId = ++id, Title Goes Here", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Alcohol Fueled Brewtality Live! [Disc 1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Alcohol Fueled Brewtality Live! [Disc 2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Alive 2007", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "All I Ask of You", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Amen (So Be It)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Animal Vehicle", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Axis of Awesome"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ao Vivo [IMPORT]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Zeca Pagodinho"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Apocalyptic Love", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Slash"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Appetite for Destruction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Are You Experienced?", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jimi Hendrix"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Arquivo II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Arquivo Os Paralamas Do Sucesso", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "A-Sides", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Audioslave", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Automatic for the People", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Axé Bahia 2001", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Babel", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Mumford & Sons"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bach: Goldberg Variations", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wilhelm Kempff"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bach: The Brandenburg Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestra of The Age of Enlightenment"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bach: The Cello Suites", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yo-Yo Ma"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bach: Toccata & Fugue in D Minor", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Ton Koopman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bad Motorfinger", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Balls to the Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Banadeek Ta'ala", Genre = genres["World"], Price = 8.99M, Artist = artists["Amr Diab"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Barbie Girl", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Aqua"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bark at the Moon (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bartok: Violin & Viola Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yehudi Menuhin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Barulhinho Bom", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marisa Monte"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "BBC Sessions [Disc 1] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "BBC Sessions [Disc 2] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Be Here Now", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Oasis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bedrock 11 Compiled & Mixed", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["John Digweed"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Berlioz: Symphonie Fantastique", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Beyond Good And Evil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Cult"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Big Bad Wolf ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Armand Van Helden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Big Ones", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Aerosmith"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Black Album", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Black Sabbath Vol. 4 (Remaster)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Black Sabbath", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Black", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Blackwater Park", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Blizzard of Ozz", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Blood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["In This Moment"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Blue Moods", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Incognito"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Blue", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bongo Fury", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Frank Zappa & Captain Beefheart"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Boys & Girls", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alabama Shakes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Brave New World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "B-Sides 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Bunkka", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "By The Way", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cake: B-Sides and Rarities", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Californication", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Carmina Burana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Boston Symphony Orchestra & Seiji Ozawa"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Carried to Dust (Bonus Track Version)", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Calexico"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Carry On", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Chris Cornell"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cássia Eller - Sem Limite [Disc 1]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cássia Eller"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chemical Wedding", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Bruce Dickinson"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chill: Brazil (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marcos Valle"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chill: Brazil (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chocolate Starfish And The Hot Dog Flavored Water", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Limp Bizkit"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chronicle, Vol. 1", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Chronicle, Vol. 2", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ciao, Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["TheStart"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cidade Negra - Hits", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cidade Negra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Classic Munkle: Turbo Edition", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Munkle"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Classics: The Best of Sarah Brightman", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Coda", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Come Away With Me", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Come Taste The Band", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Comfort Eagle", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Common Reaction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Uh Huh Her "], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Compositores", Genre = genres["Rock"], Price = 8.99M, Artist = artists["O Terço"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Contraband", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Velvet Revolver"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Core", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cornerstone", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Styx"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cosmicolor", Genre = genres["Rap"], Price = 8.99M, Artist = artists["M-Flo"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Cross", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Justice"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Culture of Fear", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Thievery Corporation"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Da Lama Ao Caos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Dakshina", Genre = genres["World"], Price = 8.99M, Artist = artists["Deva Premal"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Dark Side of the Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Death Magnetic", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Deep End of Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Above the Fold"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Deep Purple In Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Deixa Entrar", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Falamansa"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Deja Vu", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Crosby, Stills, Nash, and Young"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Di Korpu Ku Alma", Genre = genres["World"], Price = 8.99M, Artist = artists["Lura"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Diary of a Madman (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Diary of a Madman", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Dirt", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Diver Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Djavan Ao Vivo - Vol. 02", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Djavan Ao Vivo - Vol. 1", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Drum'n'bass for Papa", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Plug"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Duluth", Genre = genres["Country"], Price = 8.99M, Artist = artists["Trampled By Turtles"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Dummy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Portishead"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Duos II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Luciana Souza/Romero Lubambo"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Earl Scruggs and Friends", Genre = genres["Country"], Price = 8.99M, Artist = artists["Earl Scruggs"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Eden", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "El Camino", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Elegant Gypsy", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Al di Meola"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Elements Of Life", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Tiësto"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Elis Regina-Minha História", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Elis Regina"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Emergency On Planet Earth", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jamiroquai"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Emotion", Genre = genres["World"], Price = 8.99M, Artist = artists["Papa Wemba"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "English Renaissance", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The King's Singers"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Every Kind of Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Posies"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Faceless", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Godsmack"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Facelift", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Fair Warning", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Fear of a Black Planet", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Public Enemy"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Fear Of The Dark", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Feels Like Home", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Fireball", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Fly", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "For Those About To Rock We Salute You", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Four", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Blues Traveler"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Frank", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Amy Winehouse"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Further Down the Spiral", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Garage Inc. (Disc 1)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Garage Inc. (Disc 2)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Garbage", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Good News For People Who Love Bad News", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Modest Mouse"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Gordon", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Barenaked Ladies"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Górecki: Symphony No. 3", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Adrian Leaper & Doreen de Feis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Hits I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Hits II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Hits", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Duck Sauce"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greatest Kiss", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Greetings from Michigan", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Sufjan Stevens"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Group Therapy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Above & Beyond"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Handel: The Messiah (Highlights)", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Scholars Baroque Ensemble"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Haydn: Symphonies 99 - 104", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Royal Philharmonic Orchestra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Heart of the Night", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Heart On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Eagles of Death Metal"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Holy Diver", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dio"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Homework", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Hot Rocks, 1964-1971 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Houses Of The Holy", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "How To Dismantle An Atomic Bomb", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Human", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Hunky Dory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Hymns", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Hysteria", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Def Leppard"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Absentia", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Porcupine Tree"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Between", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Paul Van Dyk"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Rainbows", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Step", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan & Double Trouble"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In the court of the Crimson King", Genre = genres["Rock"], Price = 8.99M, Artist = artists["King Crimson"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Through The Out Door", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Your Honor [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "In Your Honor [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Indestructible", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rancid"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Infinity", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Journey"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Into The Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Coverdale"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Introspective", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Pet Shop Boys"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Iron Maiden", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "ISAM", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "IV", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Jagged Little Pill", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Jagged Little Pill", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Jorge Ben Jor 25 Anos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jorge Ben"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Jota Quest-1995", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jota Quest"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Kick", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["INXS"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Kill 'Em All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Kind of Blue", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "King For A Day Fool For A Lifetime", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Faith No More"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Kiss", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Carly Rae Jepsen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Last Call", Genre = genres["Country"], Price = 8.99M, Artist = artists["Cayouche"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Le Freak", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Chic"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Le Tigre", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Le Tigre"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Led Zeppelin I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Led Zeppelin II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Led Zeppelin III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Let There Be Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Little Earthquakes", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live [Disc 1]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live [Disc 2]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live After Death", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live At Donington 1992 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live At Donington 1992 (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live on Earth", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["The Cat Empire"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Live On Two Legs [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Living After Midnight", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Judas Priest"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Living", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Load", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Love Changes Everything", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "MacArthur Park Suite", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Donna Summer"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Machine Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Magical Mystery Tour", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mais Do Mesmo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Legião Urbana"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Maquinarama", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Marasim", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Jagjit Singh"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mascagni: Cavalleria Rusticana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["James Levine"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Master of Puppets", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mechanics & Mathematics", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Venus Hum"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mental Jewelry", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Live"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Metallics", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "meteora", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Meus Momentos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gonzaguinha"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mezmerize", Genre = genres["Metal"], Price = 8.99M, Artist = artists["System Of A Down"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mezzanine", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Massive Attack"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Miles Ahead", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Milton Nascimento Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Minas", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Minha Historia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Buarque"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Misplaced Childhood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Marillion"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "MK III The Final Concerts [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Morning Dance", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Motley Crue Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Mötley Crüe"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Moving Pictures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mozart: Chamber Music", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nash Ensemble"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Mozart: Symphonies Nos. 40 & 41", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Murder Ballads", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nick Cave and the Bad Seeds"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Music For The Jilted Generation", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["The Prodigy"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "My Generation - The Very Best Of The Who", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "My Name is Skrillex", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Na Pista", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cláudio Zoli"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Nevermind", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nirvana"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "New Adventures In Hi-Fi", Genre = genres["Rock"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "New Divide", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "New York Dolls", Genre = genres["Punk"], Price = 8.99M, Artist = artists["New York Dolls"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "News Of The World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Nielsen: The Six Symphonies", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Göteborgs Symfoniker & Neeme Järvi"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Night At The Opera", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Night Castle", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Trans-Siberian Orchestra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Nkolo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "No More Tears (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "No Prayer For The Dying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "No Security", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "O Brother, Where Art Thou?", Genre = genres["Country"], Price = 8.99M, Artist = artists["Alison Krauss"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "O Samba Poconé", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "O(+>", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Prince"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Oceania", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Smashing Pumpkins"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Off the Deep End", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Weird Al"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "OK Computer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Olodum", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Olodum"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "One Love", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["David Guetta"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Operation: Mindcrime", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Queensrÿche"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Opiate", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Outbreak", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Dennis Chambers"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Pachelbel: Canon & Gigue", Genre = genres["Classical"], Price = 8.99M, Artist = artists["English Concert & Trevor Pinnock"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Paid in Full", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eric B. and Rakim"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Para Siempre", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vicente Fernandez"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Pause", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Peace Sells... but Who's Buying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Physical Graffiti [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Physical Graffiti [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Physical Graffiti", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Piece Of Mind", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Pinkerton", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Plays Metallica By Four Cellos", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Apocalyptica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Pop", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Powerslave", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Prenda Minha", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Presence", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Pretty Hate Machine", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Prisoner", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Jezabels"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Privateering", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mark Knopfler"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Prokofiev: Romeo & Juliet", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Prokofiev: Symphony No.1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sergei Prokofiev & Yuri Temirkanov"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "PSY's Best 6th Part 1", Genre = genres["Pop"], Price = 8.99M, Artist = artists["PSY"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Purcell: The Fairy Queen", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Classical Players"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Purpendicular", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Purple", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Quanta Gente Veio Ver (Live)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Quanta Gente Veio ver--Bônus De Carnaval", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Quiet Songs", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aisha Duo"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Raices", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Los Tigres del Norte"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Raising Hell", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Run DMC"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Raoul and the Kings of Spain ", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tears For Fears"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rattle And Hum", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Raul Seixas", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raul Seixas"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Recovery [Explicit]", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eminem"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Reign In Blood", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Slayer"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Relayed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "ReLoad", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Respighi:Pines of Rome", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Restless and Wild", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Retrospective I (1974-1980)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Revelations", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Revolver", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ride the Lighting ", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ride The Lightning", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ring My Bell", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Anita Ward"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Riot Act", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rise of the Phoenix", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Before the Dawn"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rock In Rio [CD1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rock In Rio [CD2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rock In Rio [CD2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Roda De Funk", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Funk Como Le Gusta"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Room for Squares", Genre = genres["Pop"], Price = 8.99M, Artist = artists["John Mayer"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Root Down", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Jimmy Smith"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rounds", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rubber Factory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Rust in Peace", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Sambas De Enredo 2001", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Santana - As Years Go By", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Santana Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Saturday Night Fever", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Bee Gees"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Scary Monsters and Nice Sprites", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Scheherazade", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Chicago Symphony Orchestra & Fritz Reiner"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "SCRIABIN: Vers la flamme", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Christopher O'Riley"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Second Coming", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Serie Sem Limite (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Serie Sem Limite (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Serious About Men", Genre = genres["Rap"], Price = 8.99M, Artist = artists["The Rubberbandits"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Seventh Son of a Seventh Son", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Short Bus", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Filter"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Sibelius: Finlandia", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Singles Collection", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Six Degrees of Inner Turbulence", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dream Theater"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Slave To The Empire", Genre = genres["Metal"], Price = 8.99M, Artist = artists["T&N"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Slaves And Masters", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Slouching Towards Bethlehem", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Robert James"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Smash", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Offspring"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Something Special", Genre = genres["Country"], Price = 8.99M, Artist = artists["Dolly Parton"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Somewhere in Time", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Song(s) You Know By Heart", Genre = genres["Country"], Price = 8.99M, Artist = artists["Jimmy Buffett"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Sound of Music", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Adicts"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "South American Getaway", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The 12 Cellists of The Berlin Philharmonic"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Sozinho Remix Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Speak of the Devil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Spiritual State", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Nujabes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "St. Anger", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Still Life", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Stop Making Sense", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Talking Heads"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Stormbringer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Stranger than Fiction", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Bad Religion"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Strauss: Waltzes", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Supermodified", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Supernatural", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Surfing with the Alien (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Joe Satriani"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Switched-On Bach", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wendy Carlos"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Szymanowski: Piano Works, Vol. 1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Martin Roscoe"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Tchaikovsky: The Nutcracker", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ted Nugent", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ted Nugent"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Teflon Don", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Rick Ross"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Tell Another Joke at the Ol' Choppin' Block", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Danielson Famile"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Temple of the Dog", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Temple of the Dog"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Ten", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Texas Flood", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Battle Rages On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Beast Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paul D'Ianno"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best Of 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best of 1990–2000", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best of Beethoven", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nicolaus Esterhazy Sinfonia"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best Of Billy Cobham", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Billy Cobham"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best of Ed Motta", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Ed Motta"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Best Of Van Halen, Vol. I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Bridge", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Melanie Fiona"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Cage", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tygers of Pan Tang"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Chicago Transit Authority", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Chicago "], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Chronic", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Dr. Dre"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Colour And The Shape", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Crane Wife", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["The Decemberists"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Cream Of Clapton", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Cure", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Cure"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Dark Side Of The Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Divine Conspiracy", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Epica"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Doors", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Doors"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Dream of the Blue Turtles", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Sting"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Essential Miles Davis [Disc 1]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Essential Miles Davis [Disc 2]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Final Concerts (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Final Frontier", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Head and the Heart", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Head and the Heart"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Joshua Tree", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Last Night of the Proms", Genre = genres["Classical"], Price = 8.99M, Artist = artists["BBC Concert Orchestra"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Lumineers", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Lumineers"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Number of The Beast", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Number of The Beast", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Police Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Police"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Song Remains The Same (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Song Remains The Same (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Southern Harmony and Musical Companion", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Spade", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Butch Walker & The Black Widows"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Stone Roses", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Suburbs", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Arcade Fire"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Three Tenors Disc1/Disc2", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Carreras, Pavarotti, Domingo"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Trees They Grow So High", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "The X Factor", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Them Crooked Vultures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Them Crooked Vultures"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "This Is Happening", Genre = genres["Rock"], Price = 8.99M, Artist = artists["LCD Soundsystem"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Thunder, Lightning, Strike", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Go! Team"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Time to Say Goodbye", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Time, Love & Tenderness", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Michael Bolton"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Tomorrow Starts Today", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mobile"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Tribute", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Tuesday Night Music Club", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Sheryl Crow"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Umoja", Genre = genres["Rock"], Price = 8.99M, Artist = artists["BLØF"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Under the Pink", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Undertow", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Un-Led-Ed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Dread Zeppelin"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Unplugged [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Unplugged", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Unplugged", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Untrue", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Burial"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Use Your Illusion I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Use Your Illusion II", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Use Your Illusion II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Van Halen III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Van Halen", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Version 2.0", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Vinicius De Moraes", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vinícius De Moraes"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Virtual XI", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Voodoo Lounge", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Vozes do MPB", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Vs.", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Wagner: Favourite Overtures", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sir Georg Solti & Wiener Philharmoniker"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Walking Into Clarksdale", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Page & Plant"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Wapi Yo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "War", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Warner 25 Anos", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Wasteland R&Btheque", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raunchy"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Watermark", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Enya"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "We Were Exploding Anyway", Genre = genres["Rock"], Price = 8.99M, Artist = artists["65daysofstatic"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Weill: The Seven Deadly Sins", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestre de l'Opéra de Lyon"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "White Pony", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Who's Next", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Wish You Were Here", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "With Oden on Our Side", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Amon Amarth"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Worlds", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aaron Goldberg"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Worship Music", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Anthrax"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "X&Y", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Xinti", Genre = genres["World"], Price = 8.99M, Artist = artists["Sara Tavares"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Yano", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yano"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Yesterday Once More Disc 1/Disc 2", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Carpenters"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Zooropa", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl }, + new Album { AlbumId = ++id, Title = "Zoso", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl }, + }; + + foreach (var album in albums) + { + album.ArtistId = album.Artist.ArtistId; + album.GenreId = album.Genre.GenreId; + } + + return albums; + } + private static Dictionary artists; + private static Dictionary Artists + { + get + { + int id = 888880; + + if (artists == null) + { + var artistsList = new Artist[] + { + new Artist { ArtistId = ++id, Name = "65daysofstatic" }, + new Artist { ArtistId = ++id, Name = "Aaron Goldberg" }, + new Artist { ArtistId = ++id, Name = "Above & Beyond" }, + new Artist { ArtistId = ++id ,Name = "Above the Fold" }, + new Artist { ArtistId = ++id, Name = "AC/DC" }, + new Artist { ArtistId = ++id, Name = "Accept" }, + new Artist { ArtistId = ++id, Name = "Adicts" }, + new Artist { ArtistId = ++id, Name = "Adrian Leaper & Doreen de Feis" }, + new Artist { ArtistId = ++id, Name = "Aerosmith" }, + new Artist { ArtistId = ++id, Name = "Aisha Duo" }, + new Artist { ArtistId = ++id, Name = "Al di Meola" }, + new Artist { ArtistId = ++id, Name = "Alabama Shakes" }, + new Artist { ArtistId = ++id, Name = "Alanis Morissette" }, + new Artist { ArtistId = ++id, Name = "Alberto Turco & Nova Schola Gregoriana" }, + new Artist { ArtistId = ++id, Name = "Alice in Chains" }, + new Artist { ArtistId = ++id, Name = "Alison Krauss" }, + new Artist { ArtistId = ++id, Name = "Amon Amarth" }, + new Artist { ArtistId = ++id, Name = "Amon Tobin" }, + new Artist { ArtistId = ++id, Name = "Amr Diab" }, + new Artist { ArtistId = ++id, Name = "Amy Winehouse" }, + new Artist { ArtistId = ++id, Name = "Anita Ward" }, + new Artist { ArtistId = ++id, Name = "Anthrax" }, + new Artist { ArtistId = ++id, Name = "Antônio Carlos Jobim" }, + new Artist { ArtistId = ++id, Name = "Apocalyptica" }, + new Artist { ArtistId = ++id, Name = "Aqua" }, + new Artist { ArtistId = ++id, Name = "Armand Van Helden" }, + new Artist { ArtistId = ++id, Name = "Arcade Fire" }, + new Artist { ArtistId = ++id, Name = "Audioslave" }, + new Artist { ArtistId = ++id, Name = "Bad Religion" }, + new Artist { ArtistId = ++id, Name = "Barenaked Ladies" }, + new Artist { ArtistId = ++id, Name = "BBC Concert Orchestra" }, + new Artist { ArtistId = ++id, Name = "Bee Gees" }, + new Artist { ArtistId = ++id, Name = "Before the Dawn" }, + new Artist { ArtistId = ++id, Name = "Berliner Philharmoniker" }, + new Artist { ArtistId = ++id, Name = "Billy Cobham" }, + new Artist { ArtistId = ++id, Name = "Black Label Society" }, + new Artist { ArtistId = ++id, Name = "Black Sabbath" }, + new Artist { ArtistId = ++id, Name = "BLØF" }, + new Artist { ArtistId = ++id, Name = "Blues Traveler" }, + new Artist { ArtistId = ++id, Name = "Boston Symphony Orchestra & Seiji Ozawa" }, + new Artist { ArtistId = ++id, Name = "Britten Sinfonia, Ivor Bolton & Lesley Garrett" }, + new Artist { ArtistId = ++id, Name = "Bruce Dickinson" }, + new Artist { ArtistId = ++id, Name = "Buddy Guy" }, + new Artist { ArtistId = ++id, Name = "Burial" }, + new Artist { ArtistId = ++id, Name = "Butch Walker & The Black Widows" }, + new Artist { ArtistId = ++id, Name = "Caetano Veloso" }, + new Artist { ArtistId = ++id, Name = "Cake" }, + new Artist { ArtistId = ++id, Name = "Calexico" }, + new Artist { ArtistId = ++id, Name = "Carly Rae Jepsen" }, + new Artist { ArtistId = ++id, Name = "Carreras, Pavarotti, Domingo" }, + new Artist { ArtistId = ++id, Name = "Cássia Eller" }, + new Artist { ArtistId = ++id, Name = "Cayouche" }, + new Artist { ArtistId = ++id, Name = "Chic" }, + new Artist { ArtistId = ++id, Name = "Chicago " }, + new Artist { ArtistId = ++id, Name = "Chicago Symphony Orchestra & Fritz Reiner" }, + new Artist { ArtistId = ++id, Name = "Chico Buarque" }, + new Artist { ArtistId = ++id, Name = "Chico Science & Nação Zumbi" }, + new Artist { ArtistId = ++id, Name = "Choir Of Westminster Abbey & Simon Preston" }, + new Artist { ArtistId = ++id, Name = "Chris Cornell" }, + new Artist { ArtistId = ++id, Name = "Christopher O'Riley" }, + new Artist { ArtistId = ++id, Name = "Cidade Negra" }, + new Artist { ArtistId = ++id, Name = "Cláudio Zoli" }, + new Artist { ArtistId = ++id, Name = "Coldplay" }, + new Artist { ArtistId = ++id, Name = "Creedence Clearwater Revival" }, + new Artist { ArtistId = ++id, Name = "Crosby, Stills, Nash, and Young" }, + new Artist { ArtistId = ++id, Name = "Daft Punk" }, + new Artist { ArtistId = ++id, Name = "Danielson Famile" }, + new Artist { ArtistId = ++id, Name = "David Bowie" }, + new Artist { ArtistId = ++id, Name = "David Coverdale" }, + new Artist { ArtistId = ++id, Name = "David Guetta" }, + new Artist { ArtistId = ++id, Name = "deadmau5" }, + new Artist { ArtistId = ++id, Name = "Deep Purple" }, + new Artist { ArtistId = ++id, Name = "Def Leppard" }, + new Artist { ArtistId = ++id, Name = "Deftones" }, + new Artist { ArtistId = ++id, Name = "Dennis Chambers" }, + new Artist { ArtistId = ++id, Name = "Deva Premal" }, + new Artist { ArtistId = ++id, Name = "Dio" }, + new Artist { ArtistId = ++id, Name = "Djavan" }, + new Artist { ArtistId = ++id, Name = "Dolly Parton" }, + new Artist { ArtistId = ++id, Name = "Donna Summer" }, + new Artist { ArtistId = ++id, Name = "Dr. Dre" }, + new Artist { ArtistId = ++id, Name = "Dread Zeppelin" }, + new Artist { ArtistId = ++id, Name = "Dream Theater" }, + new Artist { ArtistId = ++id, Name = "Duck Sauce" }, + new Artist { ArtistId = ++id, Name = "Earl Scruggs" }, + new Artist { ArtistId = ++id, Name = "Ed Motta" }, + new Artist { ArtistId = ++id, Name = "Edo de Waart & San Francisco Symphony" }, + new Artist { ArtistId = ++id, Name = "Elis Regina" }, + new Artist { ArtistId = ++id, Name = "Eminem" }, + new Artist { ArtistId = ++id, Name = "English Concert & Trevor Pinnock" }, + new Artist { ArtistId = ++id, Name = "Enya" }, + new Artist { ArtistId = ++id, Name = "Epica" }, + new Artist { ArtistId = ++id, Name = "Eric B. and Rakim" }, + new Artist { ArtistId = ++id, Name = "Eric Clapton" }, + new Artist { ArtistId = ++id, Name = "Eugene Ormandy" }, + new Artist { ArtistId = ++id, Name = "Faith No More" }, + new Artist { ArtistId = ++id, Name = "Falamansa" }, + new Artist { ArtistId = ++id, Name = "Filter" }, + new Artist { ArtistId = ++id, Name = "Foo Fighters" }, + new Artist { ArtistId = ++id, Name = "Four Tet" }, + new Artist { ArtistId = ++id, Name = "Frank Zappa & Captain Beefheart" }, + new Artist { ArtistId = ++id, Name = "Fretwork" }, + new Artist { ArtistId = ++id, Name = "Funk Como Le Gusta" }, + new Artist { ArtistId = ++id, Name = "Garbage" }, + new Artist { ArtistId = ++id, Name = "Gerald Moore" }, + new Artist { ArtistId = ++id, Name = "Gilberto Gil" }, + new Artist { ArtistId = ++id, Name = "Godsmack" }, + new Artist { ArtistId = ++id, Name = "Gonzaguinha" }, + new Artist { ArtistId = ++id, Name = "Göteborgs Symfoniker & Neeme Järvi" }, + new Artist { ArtistId = ++id, Name = "Guns N' Roses" }, + new Artist { ArtistId = ++id, Name = "Gustav Mahler" }, + new Artist { ArtistId = ++id, Name = "In This Moment" }, + new Artist { ArtistId = ++id, Name = "Incognito" }, + new Artist { ArtistId = ++id, Name = "INXS" }, + new Artist { ArtistId = ++id, Name = "Iron Maiden" }, + new Artist { ArtistId = ++id, Name = "Jagjit Singh" }, + new Artist { ArtistId = ++id, Name = "James Levine" }, + new Artist { ArtistId = ++id, Name = "Jamiroquai" }, + new Artist { ArtistId = ++id, Name = "Jimi Hendrix" }, + new Artist { ArtistId = ++id, Name = "Jimmy Buffett" }, + new Artist { ArtistId = ++id, Name = "Jimmy Smith" }, + new Artist { ArtistId = ++id, Name = "Joe Satriani" }, + new Artist { ArtistId = ++id, Name = "John Digweed" }, + new Artist { ArtistId = ++id, Name = "John Mayer" }, + new Artist { ArtistId = ++id, Name = "Jorge Ben" }, + new Artist { ArtistId = ++id, Name = "Jota Quest" }, + new Artist { ArtistId = ++id, Name = "Journey" }, + new Artist { ArtistId = ++id, Name = "Judas Priest" }, + new Artist { ArtistId = ++id, Name = "Julian Bream" }, + new Artist { ArtistId = ++id, Name = "Justice" }, + new Artist { ArtistId = ++id, Name = "Orchestre de l'Opéra de Lyon" }, + new Artist { ArtistId = ++id, Name = "King Crimson" }, + new Artist { ArtistId = ++id, Name = "Kiss" }, + new Artist { ArtistId = ++id, Name = "LCD Soundsystem" }, + new Artist { ArtistId = ++id, Name = "Le Tigre" }, + new Artist { ArtistId = ++id, Name = "Led Zeppelin" }, + new Artist { ArtistId = ++id, Name = "Legião Urbana" }, + new Artist { ArtistId = ++id, Name = "Lenny Kravitz" }, + new Artist { ArtistId = ++id, Name = "Les Arts Florissants & William Christie" }, + new Artist { ArtistId = ++id, Name = "Limp Bizkit" }, + new Artist { ArtistId = ++id, Name = "Linkin Park" }, + new Artist { ArtistId = ++id, Name = "Live" }, + new Artist { ArtistId = ++id, Name = "Lokua Kanza" }, + new Artist { ArtistId = ++id, Name = "London Symphony Orchestra" }, + new Artist { ArtistId = ++id, Name = "Los Tigres del Norte" }, + new Artist { ArtistId = ++id, Name = "Luciana Souza/Romero Lubambo" }, + new Artist { ArtistId = ++id, Name = "Lulu Santos" }, + new Artist { ArtistId = ++id, Name = "Lura" }, + new Artist { ArtistId = ++id, Name = "Marcos Valle" }, + new Artist { ArtistId = ++id, Name = "Marillion" }, + new Artist { ArtistId = ++id, Name = "Marisa Monte" }, + new Artist { ArtistId = ++id, Name = "Mark Knopfler" }, + new Artist { ArtistId = ++id, Name = "Martin Roscoe" }, + new Artist { ArtistId = ++id, Name = "Massive Attack" }, + new Artist { ArtistId = ++id, Name = "Maurizio Pollini" }, + new Artist { ArtistId = ++id, Name = "Megadeth" }, + new Artist { ArtistId = ++id, Name = "Mela Tenenbaum, Pro Musica Prague & Richard Kapp" }, + new Artist { ArtistId = ++id, Name = "Melanie Fiona" }, + new Artist { ArtistId = ++id, Name = "Men At Work" }, + new Artist { ArtistId = ++id, Name = "Metallica" }, + new Artist { ArtistId = ++id, Name = "M-Flo" }, + new Artist { ArtistId = ++id, Name = "Michael Bolton" }, + new Artist { ArtistId = ++id, Name = "Michael Tilson Thomas" }, + new Artist { ArtistId = ++id, Name = "Miles Davis" }, + new Artist { ArtistId = ++id, Name = "Milton Nascimento" }, + new Artist { ArtistId = ++id, Name = "Mobile" }, + new Artist { ArtistId = ++id, Name = "Modest Mouse" }, + new Artist { ArtistId = ++id, Name = "Mötley Crüe" }, + new Artist { ArtistId = ++id, Name = "Motörhead" }, + new Artist { ArtistId = ++id, Name = "Mumford & Sons" }, + new Artist { ArtistId = ++id, Name = "Munkle" }, + new Artist { ArtistId = ++id, Name = "Nash Ensemble" }, + new Artist { ArtistId = ++id, Name = "Neil Young" }, + new Artist { ArtistId = ++id, Name = "New York Dolls" }, + new Artist { ArtistId = ++id, Name = "Nick Cave and the Bad Seeds" }, + new Artist { ArtistId = ++id, Name = "Nicolaus Esterhazy Sinfonia" }, + new Artist { ArtistId = ++id, Name = "Nine Inch Nails" }, + new Artist { ArtistId = ++id, Name = "Nirvana" }, + new Artist { ArtistId = ++id, Name = "Norah Jones" }, + new Artist { ArtistId = ++id, Name = "Nujabes" }, + new Artist { ArtistId = ++id, Name = "O Terço" }, + new Artist { ArtistId = ++id, Name = "Oasis" }, + new Artist { ArtistId = ++id, Name = "Olodum" }, + new Artist { ArtistId = ++id, Name = "Opeth" }, + new Artist { ArtistId = ++id, Name = "Orchestra of The Age of Enlightenment" }, + new Artist { ArtistId = ++id, Name = "Os Paralamas Do Sucesso" }, + new Artist { ArtistId = ++id, Name = "Ozzy Osbourne" }, + new Artist { ArtistId = ++id, Name = "Paddy Casey" }, + new Artist { ArtistId = ++id, Name = "Page & Plant" }, + new Artist { ArtistId = ++id, Name = "Papa Wemba" }, + new Artist { ArtistId = ++id, Name = "Paul D'Ianno" }, + new Artist { ArtistId = ++id, Name = "Paul Oakenfold" }, + new Artist { ArtistId = ++id, Name = "Paul Van Dyk" }, + new Artist { ArtistId = ++id, Name = "Pearl Jam" }, + new Artist { ArtistId = ++id, Name = "Pet Shop Boys" }, + new Artist { ArtistId = ++id, Name = "Pink Floyd" }, + new Artist { ArtistId = ++id, Name = "Plug" }, + new Artist { ArtistId = ++id, Name = "Porcupine Tree" }, + new Artist { ArtistId = ++id, Name = "Portishead" }, + new Artist { ArtistId = ++id, Name = "Prince" }, + new Artist { ArtistId = ++id, Name = "Projected" }, + new Artist { ArtistId = ++id, Name = "PSY" }, + new Artist { ArtistId = ++id, Name = "Public Enemy" }, + new Artist { ArtistId = ++id, Name = "Queen" }, + new Artist { ArtistId = ++id, Name = "Queensrÿche" }, + new Artist { ArtistId = ++id, Name = "R.E.M." }, + new Artist { ArtistId = ++id, Name = "Radiohead" }, + new Artist { ArtistId = ++id, Name = "Rancid" }, + new Artist { ArtistId = ++id, Name = "Raul Seixas" }, + new Artist { ArtistId = ++id, Name = "Raunchy" }, + new Artist { ArtistId = ++id, Name = "Red Hot Chili Peppers" }, + new Artist { ArtistId = ++id, Name = "Rick Ross" }, + new Artist { ArtistId = ++id, Name = "Robert James" }, + new Artist { ArtistId = ++id, Name = "London Classical Players" }, + new Artist { ArtistId = ++id, Name = "Royal Philharmonic Orchestra" }, + new Artist { ArtistId = ++id, Name = "Run DMC" }, + new Artist { ArtistId = ++id, Name = "Rush" }, + new Artist { ArtistId = ++id, Name = "Santana" }, + new Artist { ArtistId = ++id, Name = "Sara Tavares" }, + new Artist { ArtistId = ++id, Name = "Sarah Brightman" }, + new Artist { ArtistId = ++id, Name = "Sasha" }, + new Artist { ArtistId = ++id, Name = "Scholars Baroque Ensemble" }, + new Artist { ArtistId = ++id, Name = "Scorpions" }, + new Artist { ArtistId = ++id, Name = "Sergei Prokofiev & Yuri Temirkanov" }, + new Artist { ArtistId = ++id, Name = "Sheryl Crow" }, + new Artist { ArtistId = ++id, Name = "Sir Georg Solti & Wiener Philharmoniker" }, + new Artist { ArtistId = ++id, Name = "Skank" }, + new Artist { ArtistId = ++id, Name = "Skrillex" }, + new Artist { ArtistId = ++id, Name = "Slash" }, + new Artist { ArtistId = ++id, Name = "Slayer" }, + new Artist { ArtistId = ++id, Name = "Soul-Junk" }, + new Artist { ArtistId = ++id, Name = "Soundgarden" }, + new Artist { ArtistId = ++id, Name = "Spyro Gyra" }, + new Artist { ArtistId = ++id, Name = "Stevie Ray Vaughan & Double Trouble" }, + new Artist {ArtistId = ++id, Name = "Stevie Ray Vaughan" }, + new Artist {ArtistId = ++id, Name = "Sting" }, + new Artist {ArtistId = ++id, Name = "Stone Temple Pilots" }, + new Artist {ArtistId = ++id, Name = "Styx" }, + new Artist {ArtistId = ++id, Name = "Sufjan Stevens" }, + new Artist {ArtistId = ++id, Name = "Supreme Beings of Leisure" }, + new Artist {ArtistId = ++id, Name = "System Of A Down" }, + new Artist {ArtistId = ++id, Name = "T&N" }, + new Artist {ArtistId = ++id, Name = "Talking Heads" }, + new Artist {ArtistId = ++id, Name = "Tears For Fears" }, + new Artist {ArtistId = ++id, Name = "Ted Nugent" }, + new Artist {ArtistId = ++id, Name = "Temple of the Dog" }, + new Artist {ArtistId = ++id, Name = "Terry Bozzio, Tony Levin & Steve Stevens" }, + new Artist {ArtistId = ++id, Name = "The 12 Cellists of The Berlin Philharmonic" }, + new Artist {ArtistId = ++id, Name = "The Axis of Awesome" }, + new Artist {ArtistId = ++id, Name = "The Beatles" }, + new Artist {ArtistId = ++id, Name = "The Black Crowes" }, + new Artist {ArtistId = ++id, Name = "The Black Keys" }, + new Artist {ArtistId = ++id, Name = "The Carpenters" }, + new Artist {ArtistId = ++id, Name = "The Cat Empire" }, + new Artist {ArtistId = ++id, Name = "The Cult" }, + new Artist {ArtistId = ++id, Name = "The Cure" }, + new Artist {ArtistId = ++id, Name = "The Decemberists" }, + new Artist {ArtistId = ++id, Name = "The Doors" }, + new Artist {ArtistId = ++id, Name = "The Eagles of Death Metal" }, + new Artist {ArtistId = ++id, Name = "The Go! Team" }, + new Artist {ArtistId = ++id, Name = "The Head and the Heart" }, + new Artist {ArtistId = ++id, Name = "The Jezabels" }, + new Artist {ArtistId = ++id, Name = "The King's Singers" }, + new Artist {ArtistId = ++id, Name = "The Lumineers" }, + new Artist {ArtistId = ++id, Name = "The Offspring" }, + new Artist {ArtistId = ++id, Name = "The Police" }, + new Artist {ArtistId = ++id, Name = "The Posies" }, + new Artist {ArtistId = ++id, Name = "The Prodigy" }, + new Artist {ArtistId = ++id, Name = "The Rolling Stones" }, + new Artist {ArtistId = ++id, Name = "The Rubberbandits" }, + new Artist {ArtistId = ++id, Name = "The Smashing Pumpkins" }, + new Artist {ArtistId = ++id, Name = "The Stone Roses" }, + new Artist {ArtistId = ++id, Name = "The Who" }, + new Artist {ArtistId = ++id, Name = "Them Crooked Vultures" }, + new Artist {ArtistId = ++id, Name = "TheStart" }, + new Artist {ArtistId = ++id, Name = "Thievery Corporation" }, + new Artist {ArtistId = ++id, Name = "Tiësto" }, + new Artist {ArtistId = ++id, Name = "Tim Maia" }, + new Artist {ArtistId = ++id, Name = "Ton Koopman" }, + new Artist {ArtistId = ++id, Name = "Tool" }, + new Artist {ArtistId = ++id, Name = "Tori Amos" }, + new Artist {ArtistId = ++id, Name = "Trampled By Turtles" }, + new Artist {ArtistId = ++id, Name = "Trans-Siberian Orchestra" }, + new Artist {ArtistId = ++id, Name = "Tygers of Pan Tang" }, + new Artist {ArtistId = ++id, Name = "U2" }, + new Artist {ArtistId = ++id, Name = "UB40" }, + new Artist {ArtistId = ++id, Name = "Uh Huh Her " }, + new Artist {ArtistId = ++id, Name = "Van Halen" }, + new Artist {ArtistId = ++id, Name = "Various Artists" }, + new Artist {ArtistId = ++id, Name = "Velvet Revolver" }, + new Artist {ArtistId = ++id, Name = "Venus Hum" }, + new Artist {ArtistId = ++id, Name = "Vicente Fernandez" }, + new Artist {ArtistId = ++id, Name = "Vinícius De Moraes" }, + new Artist {ArtistId = ++id, Name = "Weezer" }, + new Artist {ArtistId = ++id, Name = "Weird Al" }, + new Artist {ArtistId = ++id, Name = "Wendy Carlos" }, + new Artist {ArtistId = ++id, Name = "Wilhelm Kempff" }, + new Artist {ArtistId = ++id, Name = "Yano" }, + new Artist {ArtistId = ++id, Name = "Yehudi Menuhin" }, + new Artist {ArtistId = ++id, Name = "Yes" }, + new Artist {ArtistId = ++id, Name = "Yo-Yo Ma" }, + new Artist {ArtistId = ++id, Name = "Zeca Pagodinho" }, + //new Artist { Name = "אריק אינשטיין"} + }; + + artists = new Dictionary(); + foreach (Artist artist in artistsList) + { + artists.Add(artist.Name, artist); + } + } + + return artists; + } + } + private static Dictionary genres; + private static Dictionary Genres + { + get + { + int id = 7777770; + if (genres == null) + { + var genresList = new Genre[] + { + new Genre { GenreId = ++id, Name = "Pop" }, + new Genre { GenreId = ++id, Name = "Rock" }, + new Genre { GenreId = ++id, Name = "Jazz" }, + new Genre { GenreId = ++id, Name = "Metal" }, + new Genre { GenreId = ++id, Name = "Electronic" }, + new Genre { GenreId = ++id, Name = "Blues" }, + new Genre { GenreId = ++id, Name = "Latin" }, + new Genre { GenreId = ++id, Name = "Rap" }, + new Genre { GenreId = ++id, Name = "Classical" }, + new Genre { GenreId = ++id, Name = "Alternative" }, + new Genre { GenreId = ++id, Name = "Country" }, + new Genre { GenreId = ++id, Name = "R&B" }, + new Genre { GenreId = ++id, Name = "Indie" }, + new Genre { GenreId = ++id, Name = "Punk" }, + new Genre { GenreId = ++id, Name = "World" } + }; + + genres = new Dictionary(); + + foreach (Genre genre in genresList) + { + genres.Add(genre.Name, genre); + } + } + + return genres; + } + } + private static void BuildFallbackData() + { + var albums = GetAlbums(); + Array.Resize(ref albums, 100); + _fallbackAlbums = albums.ToList(); + + + Dictionary genres = new Dictionary(); + Dictionary artists = new Dictionary(); + + foreach (var a in FallbackAlbums) + { + var genre = a.Genre; + a.GenreId = genre.GenreId; + + var artist = a.Artist; + a.ArtistId = artist.ArtistId; + + if (!genres.ContainsKey(genre.GenreId)) + { + genres.Add(genre.GenreId, genre); + } + + if (genre.Albums == null) + { + genre.Albums = new List(); + } + genre.Albums.Add(a); + + if (!artists.ContainsKey(artist.ArtistId)) + { + artists.Add(artist.ArtistId, artist); + } + } + + _fallbackGenre = genres.Values.ToList(); + _fallbackArtists = artists.Values.ToList(); + } + + private static List _fallbackAlbums; + public static List FallbackAlbums + { + get + { + return _fallbackAlbums; + } + } + private static List _fallbackGenre; + public static List FallbackGenres + { + get + { + return _fallbackGenre; + } + } + + private static List _fallbackArtists; + public static List FallbackArtists + { + get + { + return _fallbackArtists; + } + } } } diff --git a/MusicStore/src/MusicStoreUI/Models/ShoppingCart.cs b/MusicStore/src/MusicStoreUI/Models/ShoppingCart.cs index 3539c758..1b530a8e 100644 --- a/MusicStore/src/MusicStoreUI/Models/ShoppingCart.cs +++ b/MusicStore/src/MusicStoreUI/Models/ShoppingCart.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading.Tasks; using MusicStoreUI.Services; using Microsoft.AspNetCore.Http; -using MusicStoreUI.Services.HystrixCommands; namespace MusicStoreUI.Models { @@ -117,8 +116,7 @@ namespace MusicStoreUI.Models // Iterate over the items in the cart, adding the order details for each foreach (var item in cartItems) { - var albumCommand = new AlbumCommand("GetAlbum", _musicStore, item.AlbumId); - var album = await albumCommand.ExecuteAsync(); + var album = await _musicStore.GetAlbumAsync(item.AlbumId); album.OrderCount = +item.Count; albumUpdates.Add(album); @@ -146,7 +144,7 @@ namespace MusicStoreUI.Models await EmptyCartAsync(); // Update order count in albums - foreach(var a in albumUpdates) + foreach (var a in albumUpdates) { await _musicStore.UpdateAlbumAsync(a); } @@ -163,8 +161,7 @@ namespace MusicStoreUI.Models } foreach (var item in items) { - var albumCommand = new AlbumCommand("GetAlbum", _musicStore, item.AlbumId); - var album = await albumCommand.ExecuteAsync(); + var album = await _musicStore.GetAlbumAsync(item.AlbumId); item.Album = album; } } @@ -179,10 +176,9 @@ namespace MusicStoreUI.Models //A GUID to hold the cartId. cartId = Guid.NewGuid().ToString(); context.Session.SetString("Session", cartId); - } var result = await shoppingCart.CreateCartAsync(cartId); return cartId; } } -} +} \ No newline at end of file diff --git a/MusicStore/src/MusicStoreUI/MusicStoreUI.csproj b/MusicStore/src/MusicStoreUI/MusicStoreUI.csproj index 108a9e8a..870cae50 100755 --- a/MusicStore/src/MusicStoreUI/MusicStoreUI.csproj +++ b/MusicStore/src/MusicStoreUI/MusicStoreUI.csproj @@ -11,40 +11,52 @@ PreserveNewest + PreserveNewest - + + + + - + + + - + + - + + + + + + - - - - + + + - + - + + diff --git a/MusicStore/src/MusicStoreUI/Program.cs b/MusicStore/src/MusicStoreUI/Program.cs index 3a243a08..c8c19a03 100644 --- a/MusicStore/src/MusicStoreUI/Program.cs +++ b/MusicStore/src/MusicStoreUI/Program.cs @@ -15,6 +15,7 @@ namespace MusicStoreUI { public static void Main(string[] args) { + IConfiguration config = null; var host = new WebHostBuilder() diff --git a/MusicStore/src/MusicStoreUI/Services/BaseDiscoveryService.cs b/MusicStore/src/MusicStoreUI/Services/BaseDiscoveryService.cs index d6eb9423..eb7a5063 100644 --- a/MusicStore/src/MusicStoreUI/Services/BaseDiscoveryService.cs +++ b/MusicStore/src/MusicStoreUI/Services/BaseDiscoveryService.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; -using Pivotal.Discovery.Client; +using Steeltoe.Common.Discovery; using System; using System.IO; using System.Net; @@ -39,9 +39,10 @@ namespace MusicStoreUI.Services catch (Exception e) { _logger?.LogError("Invoke exception: {0}", e); + throw; } - return false; + //return false; } public virtual async Task Invoke(HttpRequestMessage request, object content) { @@ -58,9 +59,10 @@ namespace MusicStoreUI.Services catch (Exception e) { _logger?.LogError("Invoke exception: {0}", e); + throw; } - return false; + //return false; } public virtual async Task Invoke(HttpRequestMessage request, object content = null) @@ -81,17 +83,25 @@ namespace MusicStoreUI.Services catch (Exception e) { _logger?.LogError("Invoke exception: {0}", e); + throw; } - return default(T); + //return default(T); } public virtual T Deserialize(Stream stream) { - using (JsonReader reader = new JsonTextReader(new StreamReader(stream))) + try { - JsonSerializer serializer = new JsonSerializer(); - return (T)serializer.Deserialize(reader, typeof(T)); + using (JsonReader reader = new JsonTextReader(new StreamReader(stream))) + { + JsonSerializer serializer = new JsonSerializer(); + return (T)serializer.Deserialize(reader, typeof(T)); + } + } catch(Exception e) + { + _logger?.LogError("Deserialize exception: {0}", e); + throw; } } diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumCommand.cs deleted file mode 100644 index d2bdab32..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumCommand.cs +++ /dev/null @@ -1,52 +0,0 @@ -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class AlbumCommand : HystrixCommand - { - private IMusicStore _storeService; - private int? _intId; - private string _title; - - public AlbumCommand(string GroupKeyName, IMusicStore storeService, int id) : base(HystrixCommandGroupKeyDefault.AsKey(GroupKeyName)) - { - _storeService = storeService; - _intId = id; - } - - public AlbumCommand(string GroupKeyName, IMusicStore storeService, string title) : base(HystrixCommandGroupKeyDefault.AsKey(GroupKeyName)) - { - _storeService = storeService; - _title = title; - } - - protected override async Task RunAsync() - { - if (_intId != null) - { - return await _storeService.GetAlbumAsync((int)_intId); - } - else - { - return await _storeService.GetAlbumAsync(_title); - } - } - - protected override async Task RunFallbackAsync() - { - return await Task.FromResult(new Album - { - Title = "Waiting", - AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", - Artist = new Artist { Name = "The Backup Plan"}, - Genre = new Genre { - GenreId = 0, - Name = "Fallback", - Description = "The music store service is not available right now", - } - }); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsAllCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsAllCommand.cs deleted file mode 100644 index 73eed536..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsAllCommand.cs +++ /dev/null @@ -1,32 +0,0 @@ -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class AlbumsAllCommand : HystrixCommand> - { - private IMusicStore _storeService; - - public AlbumsAllCommand(string GroupKeyName, IMusicStore StoreService) : base(HystrixCommandGroupKeyDefault.AsKey(GroupKeyName)) - { - _storeService = StoreService; - } - - protected override async Task> RunAsync() - { - return await _storeService.GetAllAlbumsAsync(); - } - - protected override async Task> RunFallbackAsync() - { - var fallbackResult = new List - { - new Album { Title = "Waiting", AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", Artist = new Artist { Name = "The Backup Plan"} } - }; - - return await Task.FromResult(fallbackResult); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsTopCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsTopCommand.cs deleted file mode 100644 index 7a4075e0..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/AlbumsTopCommand.cs +++ /dev/null @@ -1,34 +0,0 @@ -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class AlbumsTopCommand : HystrixCommand> - { - private IMusicStore _storeService; - private int _count; - - public AlbumsTopCommand(string GroupKeyName, IMusicStore StoreService, int Count) : base(HystrixCommandGroupKeyDefault.AsKey(GroupKeyName)) - { - _count = Count; - _storeService = StoreService; - } - - protected override async Task> RunAsync() - { - return await _storeService.GetTopSellingAlbumsAsync(_count); - } - - protected override async Task> RunFallbackAsync() - { - var fallbackResult = new List - { - new Album { Title = "Waiting", AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", Artist = new Artist { Name = "The Backup Plan"} } - }; - - return await Task.FromResult(fallbackResult); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/ArtistsAllCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/ArtistsAllCommand.cs deleted file mode 100644 index ca7a8e17..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/ArtistsAllCommand.cs +++ /dev/null @@ -1,32 +0,0 @@ -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class ArtistsAllCommand : HystrixCommand> - { - private IMusicStore _storeService; - - public ArtistsAllCommand(string GroupKeyName, IMusicStore StoreService) : base(HystrixCommandGroupKeyDefault.AsKey(GroupKeyName)) - { - _storeService = StoreService; - } - - protected override async Task> RunAsync() - { - return await _storeService.GetAllArtistsAsync(); - } - - protected override async Task> RunFallbackAsync() - { - var fallbackResult = new List - { - new Artist { Name = "The Backup Plan"} - }; - - return await Task.FromResult(fallbackResult); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenreCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenreCommand.cs deleted file mode 100644 index 39362ef5..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenreCommand.cs +++ /dev/null @@ -1,56 +0,0 @@ -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class GenreCommand : HystrixCommand - { - private IMusicStore _storeService; - private int? _intId; - private string _stringId; - - public GenreCommand(string groupKey, IMusicStore storeService, int id) : base(HystrixCommandGroupKeyDefault.AsKey(groupKey)) - { - _storeService = storeService; - _intId = id; - } - - public GenreCommand(string groupKey, IMusicStore storeService, string id) : base(HystrixCommandGroupKeyDefault.AsKey(groupKey)) - { - _storeService = storeService; - _stringId = id; - } - - protected override async Task RunAsync() - { - if (_intId != null) - { - return await _storeService.GetGenreAsync((int)_intId); - } - else - { - return await _storeService.GetGenreAsync(_stringId); - } - } - - protected override async Task RunFallbackAsync() - { - return await Task.FromResult( - new Genre - { - GenreId = 0, - Name = "Fallback", - Description = "The music store service is not available right now", - Albums = new List - { - new Album { - Title = "Waiting", AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", - Artist = new Artist { Name = "The Backup Plan"} - } - } - }); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenresCommand.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenresCommand.cs deleted file mode 100644 index 6e902572..00000000 --- a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GenresCommand.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.Extensions.Logging; -using MusicStoreUI.Models; -using Steeltoe.CircuitBreaker.Hystrix; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MusicStoreUI.Services.HystrixCommands -{ - public class GenresCommand : HystrixCommand> - { - private IMusicStore _storeService; - - public GenresCommand(IHystrixCommandGroupKey groupKey, IMusicStore storeService) : base(groupKey) - { - _storeService = storeService; - } - - protected override async Task> RunAsync() - { - return await _storeService.GetGenresAsync(); - } - - protected override async Task> RunFallbackAsync() - { - List results = new List - { - new Genre - { - GenreId = 0, - Name = "Fallback", - Description = "The music store service is not available right now", - Albums = new List - { - new Album { - Title = "Waiting", AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", - Artist = new Artist { Name = "The Backup Plan"} - } - } - } - }; - return await Task.FromResult(results); - } - } -} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetAlbum.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetAlbum.cs new file mode 100644 index 00000000..2d8699a3 --- /dev/null +++ b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetAlbum.cs @@ -0,0 +1,181 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Model = MusicStoreUI.Models; +using Steeltoe.CircuitBreaker.Hystrix; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System; + +namespace MusicStoreUI.Services.HystrixCommands +{ + public class GetAlbum : HystrixCommand + { + private const int CACHE_TIME = 30; + + private IMusicStore _storeService; + private IMemoryCache _cache; + private AppSettings _appSettings; + private ILogger _logger; + private int _intId; + private string _name; + + + public GetAlbum( + IHystrixCommandOptions options, + IMusicStore storeService, + IMemoryCache cache, + IOptions appsettings, + ILogger logger + ) : base(options) + { + _storeService = storeService; + _cache = cache; + _appSettings = appsettings.Value; + _logger = logger; + this.IsFallbackUserDefined = true; + } + + public async Task GetAlbumAsync(int id) + { + _intId = id; + return await ExecuteAsync(); + } + public async Task GetAlbumAsync(string name) + { + _name = name; + return await ExecuteAsync(); + } + + protected override async Task RunAsync() + { + Model.Album result = CheckCache(); + if (result != null) + { + _logger.LogInformation("Album returning from cache!"); + return result; + } + + result = await FetchFromStoreAsync(); + + CacheResult(result); + + _logger.LogInformation("Album returned from store!"); + return result; + } + + + protected override async Task RunFallbackAsync() + { + _logger.LogInformation("Album trying fallback!"); + + var result = FetchFromFallback(); + if (result != null) + { + _logger.LogInformation("Album returning from fallback cache!"); + } else + { + + result = new Model.Album() + { + AlbumArtUrl = Model.SampleData.ImageUrl, + Genre = new Model.Genre() + { + Name = "Not Available" + }, + AlbumId = 0, + Title = _name ?? "Not Available", + Artist = new Model.Artist() + { + Name = "Not Available", + ArtistId = 0 + }, + Price = 0 + }; + + _logger.LogInformation("Album returning unknown!"); + } + + return await Task.FromResult(result); + } + + private Model.Album FetchFromFallback() + { + _logger.LogInformation("Album fetching from fallback cache!"); + Model.Album result; + + if (string.IsNullOrEmpty(_name)) + { + result = Model.SampleData.FallbackAlbums.Where((p) => p.AlbumId == _intId).SingleOrDefault(); + } + else + { + result = Model.SampleData.FallbackAlbums.Where((p) => p.Title == _name).SingleOrDefault(); + } + _logger.LogInformation("Back"); + + if (result != null) + { + _logger.LogInformation("{0} = {1}", result.AlbumId, result.Title); + } + + return result; + } + + private async Task FetchFromStoreAsync() + { + if (string.IsNullOrEmpty(_name)) + { + return await _storeService.GetAlbumAsync(_intId); + } + else + { + return await _storeService.GetAlbumAsync(_name); + } + } + + private void CacheResult(Model.Album album) + { + if (album != null) + { + if (_appSettings.CacheDbResults) + { + _logger.LogInformation("Album cached"); + _cache.Set( + GetCacheKey(album.Title), + album, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + + _cache.Set( + GetCacheKey(album.AlbumId), + album, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + } + } + } + + private Model.Album CheckCache() + { + Model.Album album; + if (string.IsNullOrEmpty(_name)) + { + _cache.TryGetValue(GetCacheKey(_intId), out album); + } + else + { + _cache.TryGetValue(GetCacheKey(_name), out album); + } + return album; + } + private string GetCacheKey(T value) + { + return "Album:" + value.ToString(); + } + } + +} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenre.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenre.cs new file mode 100644 index 00000000..ca6ce87f --- /dev/null +++ b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenre.cs @@ -0,0 +1,214 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Model = MusicStoreUI.Models; +using Steeltoe.CircuitBreaker.Hystrix; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Linq; +using System; + +namespace MusicStoreUI.Services.HystrixCommands +{ + public class GetGenre : HystrixCommand + { + private const int CACHE_TIME = 30; + + private IMusicStore _storeService; + private IMemoryCache _cache; + private AppSettings _appSettings; + private ILogger _logger; + private int _intId; + private string _name; + + + public GetGenre( + IHystrixCommandOptions options, + IMusicStore storeService, + IMemoryCache cache, + IOptions appsettings, + ILogger logger + ) : base(options) + { + _storeService = storeService; + _cache = cache; + _appSettings = appsettings.Value; + _logger = logger; + this.IsFallbackUserDefined = true; + } + + public async Task GetGenreAsync(int id) + { + _intId = id; + return await ExecuteAsync(); + } + public async Task GetGenreAsync(string name) + { + _name = name; + return await ExecuteAsync(); + } + + protected override async Task RunAsync() + { + Model.Genre result = CheckCache(); + + if (result != null) + { + _logger.LogInformation("Genre returning from cache!"); + return result; + } + + result = await FetchFromStoreAsync(); + + CacheResult(result); + + _logger.LogInformation("Genre returned from store!"); + return result; + } + + protected override async Task RunFallbackAsync() + { + var result = FetchFromFallback(); + if (result != null) + { + _logger.LogInformation("Genre returning from fallback cache!"); + } + else + { + result = new Model.Genre() + { + GenreId = _intId, + Name = _name, + Albums = new List() + }; + + _logger.LogInformation("Genre returning unknown!"); + } + + return await Task.FromResult(result); + } + + private Model.Genre FetchFromFallback() + { + Model.Genre result = null; + + if (string.IsNullOrEmpty(_name)) + { + result = Model.SampleData.FallbackGenres.Where((p) => p.GenreId == _intId).SingleOrDefault(); + } + else + { + result = Model.SampleData.FallbackGenres.Where((p) => p.Name == _name).SingleOrDefault(); + } + + if (result != null) + { + _logger.LogInformation("{0} = {1}", result.GenreId, result.Name); + } + + + return result; + } + + + + private async Task FetchFromStoreAsync() + { + if (string.IsNullOrEmpty(_name)) + { + return await _storeService.GetGenreAsync(_intId); + } + else + { + return await _storeService.GetGenreAsync(_name); + } + } + + private void CacheResult(Model.Genre genre) + { + if (genre != null) + { + if (_appSettings.CacheDbResults) + { + _logger.LogInformation("Genre cached"); + _cache.Set( + GetCacheKey(genre.Name), + genre, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + + _cache.Set( + GetCacheKey(genre.GenreId), + genre, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + } + } + } + + private Model.Genre CheckCache() + { + Model.Genre genre; + if (string.IsNullOrEmpty(_name)) + { + _cache.TryGetValue(GetCacheKey(_intId), out genre); + } + else + { + _cache.TryGetValue(GetCacheKey(_name), out genre); + } + return genre; + } + private string GetCacheKey(T value) + { + return "Genre:" + value.ToString(); + } + //private IMusicStore _storeService; + //private int? _intId; + //private string _stringId; + + //public GenreCommand(string groupKey, IMusicStore storeService, int id) : base(HystrixCommandGroupKeyDefault.AsKey(groupKey)) + //{ + // _storeService = storeService; + // _intId = id; + //} + + //public GenreCommand(string groupKey, IMusicStore storeService, string id) : base(HystrixCommandGroupKeyDefault.AsKey(groupKey)) + //{ + // _storeService = storeService; + // _stringId = id; + //} + + //protected override async Task RunAsync() + //{ + // if (_intId != null) + // { + // return await _storeService.GetGenreAsync((int)_intId); + // } + // else + // { + // return await _storeService.GetGenreAsync(_stringId); + // } + //} + + //protected override async Task RunFallbackAsync() + //{ + // return await Task.FromResult( + // new Genre + // { + // GenreId = 0, + // Name = "Fallback", + // Description = "The music store service is not available right now", + // Albums = new List + // { + // new Album { + // Title = "Waiting", AlbumArtUrl = "https://images-na.ssl-images-amazon.com/images/I/416o2L2p1zL._AC_US110_.jpg", + // Artist = new Artist { Name = "The Backup Plan"} + // } + // } + // }); + //} + } +} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenres.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenres.cs new file mode 100644 index 00000000..4160eccd --- /dev/null +++ b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetGenres.cs @@ -0,0 +1,101 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Model =MusicStoreUI.Models; +using Steeltoe.CircuitBreaker.Hystrix; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MusicStoreUI.Services.HystrixCommands +{ + public class GetGenres : HystrixCommand> + { + private const int CACHE_TIME = 30; + private IMusicStore _storeService; + private IMemoryCache _cache; + private AppSettings _appSettings; + private ILogger _logger; + + private const string GENRES_DATAMODEL = "genres"; + + public GetGenres( + IHystrixCommandOptions options, + IMusicStore storeService, + IMemoryCache cache, + IOptions appsettings, + ILogger logger + ) : base(options) + { + _storeService = storeService; + _cache = cache; + _appSettings = appsettings.Value; + _logger = logger; + this.IsFallbackUserDefined = true; + } + + public async Task> GetGenresAsync() + { + return await ExecuteAsync(); + } + protected override async Task> RunAsync() + { + var genres = CheckCache(); + if (genres != null) + { + _logger.LogInformation("Genres returning from cache!"); + return genres; + } + + genres = await _storeService.GetGenresAsync(); + + CacheResults(genres); + + _logger.LogInformation("Genres returned from store!"); + return genres; + } + + + protected override async Task> RunFallbackAsync() + { + + _logger.LogInformation("Switching to fallback genres!"); + var fallbackGenres = Model.SampleData.FallbackGenres; + foreach(var g in fallbackGenres) + { + _logger.LogInformation(g.GenreId, g.Name); + } + + return await Task.FromResult(fallbackGenres); + + } + + private void CacheResults(List genres) + { + if (genres != null && genres.Count > 0) + { + if (_appSettings.CacheDbResults) + { + _logger.LogInformation("Genres caching results"); + + _cache.Set( + GENRES_DATAMODEL, + genres, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + } + } + } + + private List CheckCache() + { + List result = null; + if (_appSettings.CacheDbResults) + { + _cache.TryGetValue(GENRES_DATAMODEL, out result); + } + return result; + } + } +} diff --git a/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetTopAlbums.cs b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetTopAlbums.cs new file mode 100644 index 00000000..42e14278 --- /dev/null +++ b/MusicStore/src/MusicStoreUI/Services/HystrixCommands/GetTopAlbums.cs @@ -0,0 +1,106 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Model = MusicStoreUI.Models; +using Steeltoe.CircuitBreaker.Hystrix; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MusicStoreUI.Services.HystrixCommands +{ + public class GetTopAlbums : HystrixCommand> + { + private const int CACHE_TIME = 30; + private IMusicStore _storeService; + private int _count; + private IMemoryCache _cache; + private AppSettings _appSettings; + private ILogger _logger; + + private const string TOP_SELLING = "topselling"; + + public GetTopAlbums( + IHystrixCommandOptions options, + IMusicStore storeService, + IMemoryCache cache, + IOptions appsettings, + ILogger logger + ) : base(options) + { + _storeService = storeService; + _cache = cache; + _appSettings = appsettings.Value; + _logger = logger; + this.IsFallbackUserDefined = true; + } + + public async Task> GetTopSellingAlbumsAsync(int count) + { + _count = count; + return await ExecuteAsync(); + } + + protected override async Task> RunAsync() + { + var top = CheckCache(); + if (top != null) + { + _logger.LogInformation("TopAlbum returning from cache!"); + return top; + } + + top = await _storeService.GetTopSellingAlbumsAsync(_count); + + CacheResults(top); + + _logger.LogInformation("TopAlbum returned from store!"); + return top; + } + + + protected override async Task> RunFallbackAsync() + { + + _logger.LogInformation("TopAlbum switching to fallback Albums!"); + + var fallback = Model.SampleData.FallbackAlbums; + List results = new List(); + for (int i = 0; i < _count; i++) + { + results.Add(fallback[i]); + } + return await Task.FromResult(results); + + } + + private void CacheResults(List albums) + { + if (albums != null && albums.Count > 0) + { + if (_appSettings.CacheDbResults) + { + _logger.LogInformation("TopAlbum caching results"); + + _cache.Set( + TOP_SELLING, + albums, + new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(TimeSpan.FromSeconds(CACHE_TIME)) + .SetPriority(CacheItemPriority.High)); + } + } + } + + private List CheckCache() + { + List result = null; + if (_appSettings.CacheDbResults) + { + _cache.TryGetValue(TOP_SELLING, out result); + } + return result; + } + } +} diff --git a/MusicStore/src/MusicStoreUI/Services/MusicStoreService.cs b/MusicStore/src/MusicStoreUI/Services/MusicStoreService.cs index 410985c7..ad7f0691 100644 --- a/MusicStore/src/MusicStoreUI/Services/MusicStoreService.cs +++ b/MusicStore/src/MusicStoreUI/Services/MusicStoreService.cs @@ -1,6 +1,6 @@ using Microsoft.Extensions.Logging; using MusicStoreUI.Models; -using Pivotal.Discovery.Client; +using Steeltoe.Common.Discovery; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; diff --git a/MusicStore/src/MusicStoreUI/Services/OrderProcessingService.cs b/MusicStore/src/MusicStoreUI/Services/OrderProcessingService.cs index 34177cee..d7f4d529 100644 --- a/MusicStore/src/MusicStoreUI/Services/OrderProcessingService.cs +++ b/MusicStore/src/MusicStoreUI/Services/OrderProcessingService.cs @@ -1,11 +1,11 @@ using Microsoft.Extensions.Logging; -using Pivotal.Discovery.Client; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MusicStoreUI.Models; using System.Net.Http; +using Steeltoe.Common.Discovery; namespace MusicStoreUI.Services { diff --git a/MusicStore/src/MusicStoreUI/Services/ShoppingCartService.cs b/MusicStore/src/MusicStoreUI/Services/ShoppingCartService.cs index 710bd648..a66ee248 100644 --- a/MusicStore/src/MusicStoreUI/Services/ShoppingCartService.cs +++ b/MusicStore/src/MusicStoreUI/Services/ShoppingCartService.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Threading.Tasks; using MusicStoreUI.Models; -using Pivotal.Discovery.Client; using Microsoft.Extensions.Logging; using System.Net.Http; +using Steeltoe.Common.Discovery; namespace MusicStoreUI.Services { diff --git a/MusicStore/src/MusicStoreUI/Startup.cs b/MusicStore/src/MusicStoreUI/Startup.cs index cd7587cb..643ab07e 100644 --- a/MusicStore/src/MusicStoreUI/Startup.cs +++ b/MusicStore/src/MusicStoreUI/Startup.cs @@ -18,6 +18,7 @@ using Steeltoe.CloudFoundry.Connector.MySql.EFCore; using Steeltoe.Management.Endpoint.Health; using Steeltoe.Management.CloudFoundry; using Steeltoe.CircuitBreaker.Hystrix; +using Command = MusicStoreUI.Services.HystrixCommands; namespace MusicStoreUI { @@ -45,7 +46,7 @@ namespace MusicStoreUI services.AddDistributedMemoryCache(); #endif // Add custom health check contributor - services.AddSingleton(); + services.AddScoped(); // Add managment endpoint services services.AddCloudFoundryActuators(Configuration); @@ -65,6 +66,11 @@ namespace MusicStoreUI services.AddSingleton(); services.AddSingleton(); + services.AddHystrixCommand("MusicStore", Configuration); + services.AddHystrixCommand("MusicStore", Configuration); + services.AddHystrixCommand("MusicStore", Configuration); + services.AddHystrixCommand("MusicStore", Configuration); + services.AddMvc(); // Add memory cache services @@ -96,6 +102,9 @@ namespace MusicStoreUI // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { + // Add Hystrix Metrics context to pipeline + app.UseHystrixRequestContext(); + // Add management endpoints into pipeline app.UseCloudFoundryActuators(); @@ -129,9 +138,6 @@ namespace MusicStoreUI app.UseDiscoveryClient(); - // Add Hystrix Metrics context to pipeline - app.UseHystrixRequestContext(); - // Startup Hystrix metrics stream app.UseHystrixMetricsStream(); } diff --git a/MusicStore/src/MusicStoreUI/Views/Store/Details.cshtml b/MusicStore/src/MusicStoreUI/Views/Store/Details.cshtml index cdcab0ce..d0670574 100644 --- a/MusicStore/src/MusicStoreUI/Views/Store/Details.cshtml +++ b/MusicStore/src/MusicStoreUI/Views/Store/Details.cshtml @@ -23,7 +23,9 @@ Price:

+ @if (Model.AlbumId != 0) {

Add to cart

+ } \ No newline at end of file diff --git a/MusicStore/src/MusicStoreUI/appsettings.json b/MusicStore/src/MusicStoreUI/appsettings.json index 0e281a82..9089c32a 100755 --- a/MusicStore/src/MusicStoreUI/appsettings.json +++ b/MusicStore/src/MusicStoreUI/appsettings.json @@ -17,6 +17,13 @@ } }, "hystrix": { + "command": { + "default": { + "circuitBreaker": { + "requestVolumeThreshold": 3 + } + } + }, "stream": { "validate_certificates": false } diff --git a/MusicStore/src/MusicStoreUI/manifest-redis.yml b/MusicStore/src/MusicStoreUI/manifest-redis.yml index 648b58aa..10c91028 100644 --- a/MusicStore/src/MusicStoreUI/manifest-redis.yml +++ b/MusicStore/src/MusicStoreUI/manifest-redis.yml @@ -9,3 +9,4 @@ applications: - mStoreConfig - mStoreAccountsDB - mStoreRedis + - mStoreHystrix diff --git a/MusicStore/src/MusicStoreUI/manifest-windows-redis.yml b/MusicStore/src/MusicStoreUI/manifest-windows-redis.yml index bc344115..518ded4c 100644 --- a/MusicStore/src/MusicStoreUI/manifest-windows-redis.yml +++ b/MusicStore/src/MusicStoreUI/manifest-windows-redis.yml @@ -12,3 +12,4 @@ applications: - mStoreConfig - mStoreAccountsDB - mStoreRedis + - mStoreHystrix diff --git a/MusicStore/src/MusicStoreUI/manifest-windows.yml b/MusicStore/src/MusicStoreUI/manifest-windows.yml index 0200a82a..021486dc 100644 --- a/MusicStore/src/MusicStoreUI/manifest-windows.yml +++ b/MusicStore/src/MusicStoreUI/manifest-windows.yml @@ -11,3 +11,4 @@ applications: - mStoreRegistry - mStoreConfig - mStoreAccountsDB + - mStoreHystrix diff --git a/MusicStore/src/MusicStoreUI/manifest.yml b/MusicStore/src/MusicStoreUI/manifest.yml index 930916ad..5caf01d9 100644 --- a/MusicStore/src/MusicStoreUI/manifest.yml +++ b/MusicStore/src/MusicStoreUI/manifest.yml @@ -8,3 +8,4 @@ applications: - mStoreRegistry - mStoreConfig - mStoreAccountsDB + - mStoreHystrix diff --git a/MusicStore/src/OrderService/OrderService.csproj b/MusicStore/src/OrderService/OrderService.csproj index 653c1e84..07ff8b70 100755 --- a/MusicStore/src/OrderService/OrderService.csproj +++ b/MusicStore/src/OrderService/OrderService.csproj @@ -19,13 +19,17 @@ - + - + + + + + - - + + diff --git a/MusicStore/src/ShoppingCartService/ShoppingCartService.csproj b/MusicStore/src/ShoppingCartService/ShoppingCartService.csproj index 81f69b1d..cc376fd9 100755 --- a/MusicStore/src/ShoppingCartService/ShoppingCartService.csproj +++ b/MusicStore/src/ShoppingCartService/ShoppingCartService.csproj @@ -19,13 +19,17 @@ - + - + + + + + - - + +