For my lecture on ASP.NET Web API I needed some seed data for Entity Framework Core for the API with some relational data.

I was tired of creating this manually. Yes you have sites that can create dummy data for you but I really needed some relational data between my entities. I needed following relationships between my entities:

  • One to many
  • Many to many

I thought it would be nice if I could do this with some data from Spotify. So I began to write my own Spotify scraper to create my seed data.

Created entities

With my tool I create several classes with their own properties. The entities are created as:

  • An artist can have many albums
  • An artist can have many genres
  • An album can have one artist
  • An album can have many tracks
  • An track can have one album
  • An genre can have many artists

Database scheme

Abstract base class

using System;

public abstract class EntityBase
{
    public Guid Id { get; set; }
}

Properties

  • Id: the Id for the primary key in your database

Artist class

An Artist class that derives from the abstract EntityBase class.

using System;
using System.Collections.Generic;

public class Artist : EntityBase
{
	public string Name { get; set; }
	public int Followers { get; set; }
	public int Popularity { get; set; }
	public IEnumerable<ArtistGenre> ArtistGenres { get; set; }
	public IEnumerable<Album> Albums { get; set; }
	public string SpotifyId { get; set; }
	public Uri Image { get; set; }
}

Properties

  • Name: The name of the Artist in Spotify
  • Followers: the number of followers in Spotify
  • Popularity: the number of popularity in Spotify
  • ArtistGenres: a many-to-many class for the genres of the artist
  • Albums: a collections of the albums from the artist in Spotify
  • SpotifyId: the artist id in Spotify
  • Image: an Uri with the main image of the artist in Spotify

Album class

An Album class that derives from the abstract EntityBase class.

using System;
using System.Collections.Generic;

public class Album : EntityBase
{
	public string Name { get; set; }
	public DateTime ReleaseDate { get; set; }
	public int TotalTracks { get; set; }
	public string SpotifyId { get; set; }
	public Uri Image { get; set; }
	public Guid ArtistId { get; set; }
	public Artist Artist { get; set; }
}

Properties

  • Name: The name of the Album of an artist in Spotify
  • ReleaseDate: the release date of the album know by Spotify
  • TotalTracks: the number of tracks of the album in Spotify
  • SpotifyId: the album id in Spotify
  • Image: an Uri with the main image of the album in Spotify
  • ArtistId: the foreign key to the artist of the album
  • Artist: a navigation property to the Artist of the album

Track class

An Track class that derives from the abstract EntityBase class.

using System;

public class Track : EntityBase
{
	public string Name { get; set; }
	public string SpotifyId { get; set; }
	public int TrackNumber { get; set; }
	public int DiscNumber { get; set; }
	public int DurationMs { get; set; }
	public bool Explicit { get; set; }
	public Uri PreviewUrl { get; set; }
	public Guid AlbumId { get; set; }
	public Album Album { get; set; }
}

Properties

  • Name: The name of the Track of an album in Spotify
  • SpotifyId: the track id in Spotify
  • TrackNumber: the track number of the album know by Spotify
  • DiscNumber: the disc number of the album know by Spotify
  • DurationMs: the duration of a song in milliseconds in Spotify
  • Explicit: an Boolean if the track is marked explicit or not in Spotify
  • PreviewUrl: an Uri to listen to a preview of the track
  • AlbumId: a primary key to the album that the track belongs to
  • Album: a navigation property to the Album of the track

Genre class

An Genre class that derives from the abstract EntityBase class.

using System;
using System.Collections.Generic;

public class Genre : EntityBase
{
	public string Name { get; set; }
	public IEnumerable<ArtistGenre> ArtistGenres { get; set; }
}

Properties

  • Name: The name of the Genre in Spotify
  • ArtistGenres: the many to many navigation property to the Artists with this genre

ArtistGenre class

An ArtistGenre class.

using System;

public class ArtistGenre
{
	public Guid ArtistId { get; set; }
	public Guid GenreId { get; set; }
	public Artist Artist { get; set; }
	public Genre Genre { get; set; }
}

Properties

  • ArtistId: The PK and FK of the ArtistId
  • GenreId: The PK and FK of the GenreId
  • Artist: The navigation property of the Artist
  • Genre: The navigation property of the Genre

Created seeding

The tool will create several files for your seeding.

DbContext class

An DbContext class with the name you have chosen in the tool. In this example is the name ApplicationDbContext.

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using Namespace.Of.Your.Entities;

public class ApplicationDbContext : DbContext
{
	public DbSet<Artist> Artists  { get; set; }
	public DbSet<Genre> Genres  { get; set; }
	public DbSet<Album> Albums  { get; set; }
	public DbSet<Track> Tracks  { get; set; }
	public DbSet<ArtistGenre> ArtistGenres  { get; set; }
    
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
		modelBuilder.Entity<ArtistGenre>()
			.ToTable("ArtistGenre")
			.HasKey(ag => new { ag.ArtistId, ag.GenreId }); 
		modelBuilder.Entity<ArtistGenre>()
			.HasOne(ag => ag.Artist)
			.WithMany(g => g.ArtistGenres)
			.HasForeignKey(ag => ag.ArtistId); 
		modelBuilder.Entity<ArtistGenre>()
			.HasOne(ag => ag.Genre)
			.WithMany(a => a.ArtistGenres)
			.HasForeignKey(ag => ag.GenreId); 
		ArtistSeeder.Seed(modelBuilder);
		GenreSeeder.Seed(modelBuilder);
		AlbumSeeder.Seed(modelBuilder);
		TrackSeeder.Seed(modelBuilder);
		ArtistGenreSeeder.Seed(modelBuilder);
    }
}

Seeder classes

The tool will create five Seeder classes for the Artist, Genre, Track, Album and ArtistGenres seeding. Let's take a look to some the files.

ArtistSeeder

using Your.Entities.Namespace.Here;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

public class ArtistSeeder
{
    public static void Seed(ModelBuilder modelBuilder)
    {
		modelBuilder.Entity<Artist>().HasData(
			new Artist { Name = "Volbeat", Followers = 1733170, Popularity = 73, SpotifyId = "0L5fC7Ogm2YwgqVCRcF1bT", Image = new Uri("https://i.scdn.co/image/781539dcbee7f7d0186070c75957a0acd35dd7b9"), Id = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), },
			new Artist { Name = "Metallica", Followers = 16357199, Popularity = 84, SpotifyId = "2ye2Wgw4gimLv2eAKyk1NB", Image = new Uri("https://i.scdn.co/image/5a06711d7fc48d5e0e3f9a3274ffed3f0af1bd91"), Id = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), },
			new Artist { Name = "Queens of the Stone Age", Followers = 2524997, Popularity = 72, SpotifyId = "4pejUc4iciQfgdX6OKulQn", Image = new Uri("https://i.scdn.co/image/905233ed063a6350613c571e8508b65c3ae98080"), Id = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), }
		);
    }
}

AlbumSeeder

using Your.Entities.Namespace.Here;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;


public class AlbumSeeder
{
    
    public static void Seed(ModelBuilder modelBuilder)
    {
		modelBuilder.Entity<Album>().HasData(
			new Album { Name = "Rewind, Replay, Rebound (Live in Deutschland)", ReleaseDate = DateTime.Parse("27/11/2020 0:00:00"), TotalTracks = 27, SpotifyId = "0YmDs7WoVGrVevnmWZMA73", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738657a974616cca0510bf6d44"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("84485291-9246-44f8-ae8f-464b8eb8d214"), },
			new Album { Name = "Rewind, Replay, Rebound", ReleaseDate = DateTime.Parse("28/08/2019 0:00:00"), TotalTracks = 14, SpotifyId = "2wX5DsKkNi7yAX6tJPKh8b", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273624e2f2f108b7ce60d818693"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("7c53e1b5-d45e-4f59-975e-e8979e90f6d1"), },
			new Album { Name = "Rewind, Replay, Rebound (Deluxe)", ReleaseDate = DateTime.Parse("2/08/2019 0:00:00"), TotalTracks = 22, SpotifyId = "700dWAqcIsUkNJ1WN1XPT5", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2733664886bf7903ba384ec22d4"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("2549afc5-ce9a-4f9a-bb03-103d06afd1d9"), },
			new Album { Name = "Let's Boogie! (Live from Telia Parken)", ReleaseDate = DateTime.Parse("14/12/2018 0:00:00"), TotalTracks = 26, SpotifyId = "7MD30fGABWb74T0kKLUeTt", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273135a3f9a95ad400499d07164"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("14f9f078-1cae-4d11-bbd8-b63c0ff52af1"), },
			new Album { Name = "Seal The Deal & Let's Boogie (Deluxe)", ReleaseDate = DateTime.Parse("5/08/2016 0:00:00"), TotalTracks = 17, SpotifyId = "6h302sabU6hS5O9WWikjMS", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27356a30f800f0c513effd69593"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("1d7e85b8-8fad-48e2-83b1-c6446d3afa56"), },
			new Album { Name = "Seal The Deal & Let's Boogie", ReleaseDate = DateTime.Parse("3/06/2016 0:00:00"), TotalTracks = 17, SpotifyId = "7l1llpBs2eFfqY4MdYKuh5", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273d8b1d91e505b6d90c9f77de0"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("7d84ad3c-dadf-4027-bcf6-370ad9c25359"), },
			new Album { Name = "Outlaw Gentlemen & Shady Ladies (Deluxe Version)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 21, SpotifyId = "2As7Yojemyny2lQhClYb7l", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b02528d256d89a06ea1cbf53"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("0c41e044-55ba-4c49-af23-1a07a9bf4326"), },
			new Album { Name = "Outlaw Gentlemen & Shady Ladies", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 14, SpotifyId = "5SBrIIYCvThaqN9r1SV2pv", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27357e78d8652bc2c54332888b7"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("be2271ec-fd7a-44cd-a7a8-18968c03ef82"), },
			new Album { Name = "Beyond Hell / Above Heaven", ReleaseDate = DateTime.Parse("1/01/2012 0:00:00"), TotalTracks = 15, SpotifyId = "2sw5C70KEQdir9M85mDvYP", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c620bb589e16dff107e49e03"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("538323e4-0602-4af5-8639-77b3a1349fa6"), },
			new Album { Name = "Live From Beyond Hell / Above Heaven", ReleaseDate = DateTime.Parse("1/01/2011 0:00:00"), TotalTracks = 18, SpotifyId = "4zkQxrL6OSwXg314FlMz8z", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27390a8dcb3f3f5a8e58cb8219f"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("4a8b7fb3-f151-4288-9627-20c358a14107"), },
			new Album { Name = "Guitar Gangsters & Cadillac Blood", ReleaseDate = DateTime.Parse("1/01/2008 0:00:00"), TotalTracks = 14, SpotifyId = "6QHLhOasL7wk8EduGT7iD8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739daf215ff64034b5f9e02593"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("87283e25-3e2d-4e84-983c-3c1aaaaed6d4"), },
			new Album { Name = "Rock The Rebel / Metal The Devil", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 11, SpotifyId = "6h0IgkicJholk20m5BtTtU", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737009a136cdbba01e820c6244"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("16815483-1ac0-4ed0-94dc-6cc4c7025e24"), },
			new Album { Name = "The Strength / The Sound / The Songs", ReleaseDate = DateTime.Parse("22/04/2005 0:00:00"), TotalTracks = 15, SpotifyId = "3QA7oan9EaEIlXbfBdbck8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c33089161b2c38aeac84567b"), ArtistId = Guid.Parse("8033d0e5-3529-440f-8563-fd8aa39454d9"), Id = Guid.Parse("79d56c13-ddd5-45c9-acdc-d0d3cd0a4a27"), },
			new Album { Name = "S&M2", ReleaseDate = DateTime.Parse("28/08/2020 0:00:00"), TotalTracks = 22, SpotifyId = "7Hc3m7konwS0ugyN8vJhNg", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2731cc6d15e607e0a514b7f4b95"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("eae1b242-61d2-47a8-a46f-638c674ca8a5"), },
			new Album { Name = "Live In Brazil (1993 – 2017)", ReleaseDate = DateTime.Parse("21/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "2zhgGiT3sNBK2rbrC7JcRW", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27395958b5d219f1b328f083e08"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a4767809-47ec-4776-9a7e-69d1278f7556"), },
			new Album { Name = "Live In Argentina (1993 – 2017)", ReleaseDate = DateTime.Parse("18/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "5g3oqy7nAK03ke2cR5c95I", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2734d9b5b218dda1a963d06ee45"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("f215c77a-3ba3-46d2-a5b8-e60e2c188737"), },
			new Album { Name = "Live In Chile (1993 – 2017)", ReleaseDate = DateTime.Parse("15/04/2020 0:00:00"), TotalTracks = 18, SpotifyId = "3inFkZMAUrTnPFVSoLHb9O", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273744a08fd20f6bb5c3ffef7c5"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("635b8559-7bc0-469c-a098-8c95edffd109"), },
			new Album { Name = "Helping Hands…Live & Acoustic At The Masonic", ReleaseDate = DateTime.Parse("1/02/2019 0:00:00"), TotalTracks = 12, SpotifyId = "5tEW32iyrRuYPQQ4bwUiCf", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b4763ffbf540cd0c69bbee33"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("f17f1919-3820-436e-b3ea-e3ab90d094f6"), },
			new Album { Name = "Helping Hands...Live & Acoustic at The Masonic", ReleaseDate = DateTime.Parse("1/02/2019 0:00:00"), TotalTracks = 12, SpotifyId = "3KESkLVC8ivaWmZAoDinoc", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732861274cf2dca79cb53334b6"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cda81d17-2cb6-4cc2-9233-504cb2a49480"), },
			new Album { Name = "ライヴ・イン・テキサス1989 (Live at リユニオン・アリーナ、ダラス、1989)", ReleaseDate = DateTime.Parse("6/04/2017 0:00:00"), TotalTracks = 19, SpotifyId = "0CVEbITaSHVBJO2GnawOaj", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b9f88a8c32bbbb80f15952b4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("ec44f6ff-4d05-4449-86ea-4e547ef810bf"), },
			new Album { Name = "Hardwired…To Self-Destruct (Deluxe)", ReleaseDate = DateTime.Parse("18/11/2016 0:00:00"), TotalTracks = 26, SpotifyId = "4bcUiX49wpmDRhrC8TvDWV", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273e5a07037750e97dca575c690"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d900c9f9-d204-4f04-abb0-48a24120ba33"), },
			new Album { Name = "Hardwired…To Self-Destruct", ReleaseDate = DateTime.Parse("18/11/2016 0:00:00"), TotalTracks = 12, SpotifyId = "7LwifLL1anaEd9eIIfIkx7", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737b10c20f959932a6c790c074"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a0e3b7cc-dd05-47d3-8e79-f1361b740d01"), },
			new Album { Name = "Metallica Through The Never (Music From The Motion Picture)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 16, SpotifyId = "0ecPxTAKqXdr2MJYdYOM7e", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2736c5fb059a07c1b2b15a90280"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3b78e1b6-e634-47a9-85da-2c99dfd979e5"), },
			new Album { Name = "Metallica Through The Never (Music from the Motion Picture)", ReleaseDate = DateTime.Parse("1/01/2013 0:00:00"), TotalTracks = 16, SpotifyId = "72grIwGP38Iy2S1jxt1Gjd", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273f1a501610a71d48c526c7ecd"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3e529f44-fc67-4c2f-83e1-7caf8b11651b"), },
			new Album { Name = "Lulu", ReleaseDate = DateTime.Parse("1/11/2011 0:00:00"), TotalTracks = 10, SpotifyId = "3FgLMfp5o2h2rAny7S6h57", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273bf3f45395f620f8bbf98d919"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("82e4c858-4320-4964-8f79-4369ec64e65d"), },
			new Album { Name = "Six Feet Down Under", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 8, SpotifyId = "6PZnDE9gWetRTjw3pHbodW", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738b7be23eb07a8c5c73ef6cfa"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d8f1fb5a-54c3-4501-94cc-756fffc83598"), },
			new Album { Name = "Six Feet Down Under Part 2", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 8, SpotifyId = "0kWBvUy985muQ5E0eCGAzH", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273d19ace61eec9f6591a1c4ef2"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("21208ebd-977b-4d95-9056-31c390224d11"), },
			new Album { Name = "Death Magnetic", ReleaseDate = DateTime.Parse("12/09/2008 0:00:00"), TotalTracks = 10, SpotifyId = "0lf5ceMub7KQhLfGxCdM06", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273dfe44d577f07e08564ec73ed"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("5627a1f4-65fb-46e8-ae80-b334c5d59c18"), },
			new Album { Name = "Some Kind Of Monster", ReleaseDate = DateTime.Parse("13/07/2004 0:00:00"), TotalTracks = 8, SpotifyId = "4t0oscNTGJkXiIB2uqZYWg", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2735aa399ec78711c8e2fc42048"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("5626c26d-7ae6-44fb-85e5-e52186330dc4"), },
			new Album { Name = "Some Kind Of Monster (Live)", ReleaseDate = DateTime.Parse("13/07/2004 0:00:00"), TotalTracks = 8, SpotifyId = "3A0FTyAAcjgfhPibPsuVSc", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27396134a0376892706d87910c4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3b7b7ec3-1920-446b-9061-ca955490a387"), },
			new Album { Name = "St. Anger", ReleaseDate = DateTime.Parse("5/06/2003 0:00:00"), TotalTracks = 11, SpotifyId = "4ljK2LVKvEPd5xPgUJn0Bs", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732fe08610316f3e5ebaa06d68"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0cd651e2-b1fd-4bf2-ba57-803954204ee6"), },
			new Album { Name = "S&M", ReleaseDate = DateTime.Parse("23/11/1999 0:00:00"), TotalTracks = 21, SpotifyId = "3kVRcb2fuCcKcqltzczxRP", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2736b275d72474c508ce2b405a4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("4b57b8e6-2164-4ad6-ba04-051250f643e0"), },
			new Album { Name = "Garage, Inc.", ReleaseDate = DateTime.Parse("24/11/1998 0:00:00"), TotalTracks = 27, SpotifyId = "5b7HQ04lPT7eGJQ7fmVsjC", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737e1f85f69323acac962516c4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("032320d1-1112-47e7-968e-3b2a926fa58a"), },
			new Album { Name = "Garage Inc.", ReleaseDate = DateTime.Parse("1/01/1998 0:00:00"), TotalTracks = 27, SpotifyId = "0vshXZYhBkbIoqxyC2fXcF", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27375e6375e11550746705a9645"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("571d4078-a850-4d63-af49-1bce94ccbef2"), },
			new Album { Name = "Reload", ReleaseDate = DateTime.Parse("18/11/1997 0:00:00"), TotalTracks = 13, SpotifyId = "7KDqRmr937ylvGilPGWxfD", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273a49eff6d64cafc2551553380"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("3028af10-55f7-4d08-b0bc-367cc0834217"), },
			new Album { Name = "Load", ReleaseDate = DateTime.Parse("4/06/1996 0:00:00"), TotalTracks = 14, SpotifyId = "5rI3pfrpvmdYtGAsBwaGec", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2730a3eb7ef6df5732fc6fa77ec"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("7963cf47-4fa8-4845-9e4f-f7d58a48c921"), },
			new Album { Name = "Live S**t: Binge & Purge", ReleaseDate = DateTime.Parse("23/11/1993 0:00:00"), TotalTracks = 24, SpotifyId = "4iBN00FZaKlaXVYfxV7bBQ", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273c99dbd20668c97579417595f"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("34c175ea-f21f-4e44-bf26-ad98b7fded7a"), },
			new Album { Name = "Live Sh*t: Binge & Purge (Live In Mexico City)", ReleaseDate = DateTime.Parse("1/01/1993 0:00:00"), TotalTracks = 24, SpotifyId = "6TXWP5SAhTB9P0GN4tOT0B", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273f003fc67301640e0e99a77eb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("1cba7915-f3d2-4ff9-98a5-1fa6970034b6"), },
			new Album { Name = "Metallica", ReleaseDate = DateTime.Parse("12/08/1991 0:00:00"), TotalTracks = 12, SpotifyId = "2Kh43m04B1UkVcpcRa1Zug", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273cf84c5b276431b473e924802"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cd5ab0de-a75b-4d33-a3fc-02f18f2eabca"), },
			new Album { Name = "...And Justice for All (Remastered)", ReleaseDate = DateTime.Parse("7/09/1988 0:00:00"), TotalTracks = 9, SpotifyId = "4Cn4T0onWhfJZwWVzU5a2t", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738161357a12a172721e772e0d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("89c42f56-bd2c-4c25-a33e-c7629b3201e7"), },
			new Album { Name = "...And Justice for All (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("7/09/1988 0:00:00"), TotalTracks = 147, SpotifyId = "2XbWaerVk9fjhEiGSrd6TF", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273be54746b374358970b5e617a"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("32873e8b-b913-4d66-9190-f023e29756b5"), },
			new Album { Name = "…And Justice for All (Remastered)", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 9, SpotifyId = "6jZ1z25PyF4Yd3kHxt9rl1", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273fe896727e3db1027ed72d885"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("04cc98ef-a9c0-475f-b529-e3477a87fd62"), },
			new Album { Name = "...And Justice For All", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 9, SpotifyId = "6Eycw3dwcDMEFSqkUvLQ7g", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2737c05e69390ab7c628a83cee7"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0bd48e82-f3b2-4909-8124-aaeffbec8d69"), },
			new Album { Name = "…And Justice for All (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("25/08/1988 0:00:00"), TotalTracks = 147, SpotifyId = "2bKDte0I4SceROjBMtYtKV", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2734c9fc157cd0b0ce4196f9aeb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fa3b3a48-e692-47af-a3c4-02d9b3dec9fa"), },
			new Album { Name = "Master Of Puppets (Deluxe Box Set / Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 137, SpotifyId = "5rFZcoCvmCaJ1gxTMU4JTm", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27316d6f039fafd389911261ada"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fc834878-f512-4fb8-ab5f-a76b5665767b"), },
			new Album { Name = "Master of Puppets (Remastered Deluxe Box Set)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 137, SpotifyId = "7CGhx630DIjdJqaBDVKc5j", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273cad4832cb7b5844343278daa"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a5a4b71a-eb08-4448-bc9c-25e71455ab90"), },
			new Album { Name = "Master Of Puppets (Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 8, SpotifyId = "2Lq2qX3hYhiuPckC8Flj21", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273668e3aca3167e6e569a9aa20"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("8a15aee2-84ac-4b25-bf0a-8a133dbf6cd1"), },
			new Album { Name = "Master of Puppets (Remastered)", ReleaseDate = DateTime.Parse("3/03/1986 0:00:00"), TotalTracks = 8, SpotifyId = "5gzLOflH95LkKYE6XSXE9k", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732127e0afac383fb73d533a7d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("2725fbb3-5362-44b1-a245-ddb99a8480da"), },
			new Album { Name = "Ride The Lightning (Deluxe Remaster)", ReleaseDate = DateTime.Parse("27/07/1984 0:00:00"), TotalTracks = 63, SpotifyId = "2omIeSJEGQeKHPOpiXgfkr", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273533fd0b248052d04e6b732c0"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("006032e0-8b56-4876-bad8-672da756ccd0"), },
			new Album { Name = "Ride The Lightning (Remastered)", ReleaseDate = DateTime.Parse("27/07/1984 0:00:00"), TotalTracks = 8, SpotifyId = "1nTvIQEXvygqSIqc2vuwAz", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273b09e5084136821bf64d327f4"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("fcebeaa9-e555-4a64-82cb-f18561e14d39"), },
			new Album { Name = "Ride The Lightning (Deluxe / Remastered)", ReleaseDate = DateTime.Parse("26/07/1984 0:00:00"), TotalTracks = 64, SpotifyId = "4K5E5mWQbECn9aThu6Xnkx", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27396a926d07aea417327ea024a"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("cd4acc8b-6bc2-4c56-b5f6-c01ad099cfe5"), },
			new Album { Name = "Kill 'Em All (Deluxe Remaster)", ReleaseDate = DateTime.Parse("25/07/1983 0:00:00"), TotalTracks = 54, SpotifyId = "7GttoSWxEi5lZvIWeSrh6n", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273a4c3675649cce210651d150d"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("d83fdf25-a430-4e31-a82a-06059cb43218"), },
			new Album { Name = "Kill 'Em All (Remastered)", ReleaseDate = DateTime.Parse("25/07/1983 0:00:00"), TotalTracks = 10, SpotifyId = "0vNBQof86Lv5gLuf26ML7o", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27320292e6cce666a69ba5a86fb"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("0fd27ec2-bafc-4153-87fb-d207a24f7548"), },
			new Album { Name = "Kill 'Em All (Deluxe / Remastered)", ReleaseDate = DateTime.Parse("24/07/1983 0:00:00"), TotalTracks = 58, SpotifyId = "3m69LQokz6DaKB3yw4BH6n", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732875b8b37127cc23f6915c77"), ArtistId = Guid.Parse("9649b29e-f326-468f-a794-525e8849d9e0"), Id = Guid.Parse("a7801b99-8cda-4a30-856b-d1a08fe2a84b"), },
			new Album { Name = "Villains", ReleaseDate = DateTime.Parse("25/08/2017 0:00:00"), TotalTracks = 9, SpotifyId = "7vuIN24G18PAUAvjnICyA6", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27326e26899d11b39b400e5252c"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("4fb73071-3478-408a-a72d-5c481e53ddf1"), },
			new Album { Name = "...Like Clockwork", ReleaseDate = DateTime.Parse("3/06/2013 0:00:00"), TotalTracks = 10, SpotifyId = "5T5NM01392dvvd4EhGrCnj", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273eee7c041844e45dd76469fa0"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("2d86048a-1a1f-468d-afcf-2180aae905e3"), },
			new Album { Name = "Rated R - Deluxe Edition", ReleaseDate = DateTime.Parse("1/01/2010 0:00:00"), TotalTracks = 26, SpotifyId = "10UBEkRjqtl0iT2BRAwcto", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2730fa7b83a64a2501b6de8db39"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("c00460f8-0373-43a8-b626-2d8cba290569"), },
			new Album { Name = "Era Vulgaris", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 15, SpotifyId = "1w71aBHYJ1zTOsSsmr2Fca", Image = new Uri("https://i.scdn.co/image/ab67616d0000b27301b7dc44ae31364925b4eadc"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("89ff74e2-3da0-44ee-a3f3-70000d4bb7e3"), },
			new Album { Name = "Era Vulgaris Tour Edition", ReleaseDate = DateTime.Parse("1/01/2007 0:00:00"), TotalTracks = 24, SpotifyId = "2kJqBMlDAgX9HNfCMLlYrS", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2738597d5ec11783f4f3a33c314"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("8dea2667-5300-4ebf-b0c1-015d287a8a1e"), },
			new Album { Name = "Over The Years And Through The Woods (Live At Brixton Academy / 2005)", ReleaseDate = DateTime.Parse("22/11/2005 0:00:00"), TotalTracks = 14, SpotifyId = "2vQTLy1EZ9JPaUU68lUMgR", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273214612618a7148d52bf1913a"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("2d1ba5b8-733d-4cb3-a1b7-a00acbf55750"), },
			new Album { Name = "Lullabies To Paralyze", ReleaseDate = DateTime.Parse("1/01/2005 0:00:00"), TotalTracks = 16, SpotifyId = "68ZycIjwlQ0fvtaxVXmgn8", Image = new Uri("https://i.scdn.co/image/ab67616d0000b273ab1aaed1d2f9019183390a98"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("7fe3f405-51e9-4ca4-8383-b5016d446451"), },
			new Album { Name = "Songs For The Deaf", ReleaseDate = DateTime.Parse("1/01/2002 0:00:00"), TotalTracks = 16, SpotifyId = "4w3NeXtywU398NYW4903rY", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739eec33b045d88f87b9b06e67"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("9a307aaf-95ea-4913-973e-25c4561f9b88"), },
			new Album { Name = "Rated R", ReleaseDate = DateTime.Parse("6/06/2000 0:00:00"), TotalTracks = 12, SpotifyId = "05tJhGl52X4zGe0ySlcBk6", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2739c4d9db5d6895352b6eea6fc"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("5d1b2c31-fdf1-4734-9c1d-bc6aa9d11754"), },
			new Album { Name = "Queens of the Stone Age", ReleaseDate = DateTime.Parse("22/09/1998 0:00:00"), TotalTracks = 14, SpotifyId = "4ZVYZI1wY4TmLOQ3as1UNI", Image = new Uri("https://i.scdn.co/image/ab67616d0000b2732021e21bc55e928b744a0113"), ArtistId = Guid.Parse("6c9668ba-8e61-4188-a8a0-490c8b5a1b42"), Id = Guid.Parse("f5354d88-1b06-4724-ab92-1bfb90f52015"), }
		);
    }
}

And of course this is the same for:

  • TrackSeeder
  • GenreSeeder
  • ArtistGenreSeeder

All the entities have a foreign key Guid ID that relate to a primary key Guid ID in the seeding.

You can find my Spotify seed data generator here. Below you'll find some sort of manual to use my tool.

Spotify seed data generator manual

1. What you'll need

2. Choose your artists

3. Get your Spotify OAuth token

4. Use the Spotify seed data generator tool

5. Download the files

6. Copy folders in your project

7. Configure your connectionstring

8. Configure your Startup

9. Add migration

10. Update database

What you'll need

  • Spotify premium account (for your Spotify OAuth token)
  • ASP.NET Core application (API, MVC, Razor Pages, Blazor, ...)
  • Your favorite browser

Choose your artists

  • Click on the name of the artist to go to the artist page
  • In the address bar of your browser you can now see the Spotify Artist ID of Metallica:

  • Copy this artist ID and paste it somewhere, we will need this ID later in the tool.
  • If you want additional artists, then repeat these steps to retain their Spotify artists ID's.

Get your Spotify OAuth token

Now it's time to get your (temporary) Spotify token. We will get this temporary token from the developer site from Spotify. If you already have a Spotify token, then you can skip this step and use your own token.

  • Go to this page to get some random Spotify artists through the Spotify Console for Developers. We won't need the artists but we only go to this page to get the Spotify token in a easy way.
  • Click on the green button "GET TOKEN":

  • Login with your Spotify Credentials
  • On the next screen you don't need the check any boxes for the scopes, you can click on the green button "REQUEST TOKEN":

  • You'll obtain an OAuth Token key in the textbox like this:

  • Copy this token and paste it somewhere, because we'll need this token in the tool to identity yourself to Spotify.

Keep in mind that this token expires really quick, so maybe you'll have to repeat this steps to get a new "fresh" token from Spotify.

Use the Spotify seed data generator tool

  • Go to the Spotify seed data generator tool
  • Fill in your Spotify OAuth token
  • Fill in your Spotify artist id's (If you have multiple ID's, then separate them by a comma)
  • Choose a name for your DbContext class
  • Choose a namespace for your DbContext class
  • Choose a namespace for your entity classes
  • Click on the GO button!
  • Wait :-)

Download the files

After the tool does the scraping throught the Spotify API you can download the zip file that contains all the nessecary files:

  • In the zip file you'll find two folders; Data and Entities:

  • The Entities folder contains all the entity classes and a folder that contains the BaseEntity class:

  • The Data folder contains the DbContext class and the Seeder classes:

Copy folders in your project

Create a new ASP.NET Core web project and copy the folders where you want them to be. For example:

Configure your connectionstring

Go to your appsettings.json and add

{
  "ConnectionStrings": {
    "DefaultDatabase": "Server=(localdb)\\mssqllocaldb;Database=TEST.SpotifySeedGenerator;Trusted_Connection=True;"
  },
  ...
}

to your appsettings.json. So it would look like this. Of course you can change the database name or choose a different server.

{
  "ConnectionStrings": {
    "DefaultDatabase": "Server=(localdb)\\mssqllocaldb;Database=TEST.SpotifySeedGenerator;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Configure your Startup

Add the following code in the ConfigureServices method from your Startup.cs class:

services.AddDbContext<ApplicationDbContext>(options => 
                options.UseSqlServer(Configuration.GetConnectionString("DefaultDatabase")));

If you've chosen a different name for your DbContext than you need the change ApplicationDbContext to the name you have chosen.

Install NuGet packages

Install the following NuGet packages:

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Relational
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools (If you don't have them globally installed)

And import the required namespaces in your Startup.cs class.

Add migration

Open a PowerShell terminal at the root of your project and type in following command:

❯ dotnet ef migrations add "InitialCreate"

Update database

And to update your database type in following command:

❯ dotnet ef database update

Now open your database server manager of your choice, inspect the tables and you'll see that your tables contain data. In this example I opened the Albums table with the build-in Server Explorer in Visual Studio:

Feel free to (ab)use and/or share this tool. If you have any problems or suggestions, then ping me at Twitter, and I'll see what I can do for you.