Hearthstone, Entity Framework and JSON

Introduction

Sometimes the productivity that .NET offers is stunning! Today was one of those days that I used Entity Framework 6.0 and JSON.NET and a few lines of code to dump a JSON file into SQL server

Hearthstone

Hearthstone is a popular online card game, but for some reason in the last week 3 people I know have started playing. One was coming off a hard breakup with a smartphone game, Castle Clash, the other likes card games and the last and most important for this story is a statistician, who wants to use his skills to make his mark in Hearthstone. The statistician is my stepson who watched a video that had someone from Google who also likes Hearthstone, and knows where a JSON file is that has the info on all of the cards for the game.

Alt

The Problem

My stepson wanted to analyse the JSON file, but the tools he wanted to use prefer a database over a JSON file. We talked about how JSON and document databases are notorious for being nice for front end developers to create objects in JavaScript, but they are not so nice when you want to run reports or analyse the data within.

His initial attempt was to read the data using Python. I don’t know anything about Python, but I explained that in my languages, C# - JavaScript They have parsers that put the JSON into objects that you can use. The Python route that he used was giving the data back in a Dictionary, and parsing was tough because not every object had every field, so it was bombing on null properties.

I guessing that Python has JSON parsers, and this would be easy, but I don’t program in Python, and he was new at it. I asked him to send me the JSON and I would take see what I could do.

The Code

Creating Classes from JSON

Step one was to create classes from the JSON file. This is super easy! I first installed the “Microsoft ASP.NET and Web Tools” through Extensions and Updates under the tools menu in Visual Studio. Once this is installed I opened the JSON file in Notepad with the Hearthstone data and copied the JSON into my clipboard. Next I created a class and, in Visual Studio, under the edit menu I click the Paste special/Paste JSON as classes. This will build all the classes that you will need to save to your database.

This should create a number of classes, and one will be called Rootobject which is the root of our JSON file and that holds all ofg our other objects. It looks like this:

public class Rootobject {
        public Basic[] Basic { get; set; }
        public BlackrockMountain[] BlackrockMountain { get; set; }
        public Classic[] Classic { get; set; }
        public Credit[] Credits { get; set; }
        public CurseOfNaxxrama[] CurseofNaxxramas { get; set; }
        public Debug[] Debug { get; set; }
        public GoblinsVsGnome[] GoblinsvsGnomes { get; set; }
        public HeroSkin[] HeroSkins { get; set; }
        public Mission[] Missions { get; set; }
        public Promotion[] Promotion { get; set; }
        public Reward[] Reward { get; set; }
        public System[] System { get; set; }
        public TavernBrawl[] TavernBrawl { get; set; }
}

EntityFramework

Install EF

Next we need to install Entity Framework 6. In Visual Studio on the menu you click Project/Manage Nuget Packages, and install the package titled “EntityFramework”. As of this writing it is version 6.1.3. Yo could also add EntityFramework by running the following command in your “Package Manager Console”

Install-Package EntityFramework

Create an EF Context

Now we need to create an EF Context for our new tables. Below is the code. First we need to create a class that inherits off of DbContext. Next our constructor needs to take in a string with our connection info on it. It will need to be named “HearthStoneContext” in the config file when we get to it. Next, I added the DbSet for each class that had values in the collections in the JSON.

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace DataLayer
{
    public class HearthStoneContext : DbContext
    {
        public HearthStoneContext(): base("HearthStoneContext") {

        public DbSet<Basic> Basics { get; set; }
        public DbSet<Debug> Debugs { get; set; }
        public DbSet<Credit> Credits { get; set; }
        public DbSet<Classic> Classics { get; set; }
        public DbSet<Mission> Missions { get; set; }
        public DbSet<Reward> Rewards { get; set; }
        public DbSet<Promotion> Promotions { get; set; }
        public DbSet<System> Systems { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

Create Database

This you need a little latitude. In my case I created a new Database on my SQL Server, and then created a new user and gave him plenty of right, you can adjust these to what you’re comfortable with.

Add JSON.NET

JSON.NET is our assembly for parsing the raw JSON file. You can run Nuget from Visual Studio and search for JSON.NET, or you can get the assembly from “Package Manager Console” with:

Install-Package Newtonsoft.Json

Putting it all together!

The Code

The code below puts it all together. We get the path to the file, load the file into a string, and the let JSON.NET parse the string into our Rootobject class. Next we create an instance of our HearthStoneContext class and then load each array into the context object. Lastly, we call the save on the context class. The magic happens here! Entity Framework create the tables based on our classes in the Rootobject class and then dumps all of the data into the new tables. After you

string path = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName;
string json = File.ReadAllText(path + @"\JSON\AllSets.json");

var rootobject = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(json);

var hearthStoneContext = new HearthStoneContext();
hearthStoneContext.Basics.AddRange(rootobject.Basic);
hearthStoneContext.Classics.AddRange(rootobject.Classic);
hearthStoneContext.Credits.AddRange(rootobject.Credits);
hearthStoneContext.Debugs.AddRange(rootobject.Debug);
hearthStoneContext.Missions.AddRange(rootobject.Missions);
hearthStoneContext.Rewards.AddRange(rootobject.Reward);
hearthStoneContext.Promotions.AddRange(rootobject.Promotion);
hearthStoneContext.Systems.AddRange(rootobject.System);
hearthStoneContext.SaveChanges();

The Source Code

I put the code on GitHub here:

HearthStone Code