0

My steps:

1) Create my database in SSMS with the query

/* Execute in SQL Server Management Studio prior to building data model(s) */

CREATE DATABASE snakedb; 

GO

USE snakedb;

/*
   Create table of scores of games played. Every game will have a score recorded, but there
   will only be a corresponding name if the user enters one
*/
CREATE TABLE Scores ( id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
                      score int NOT NULL,
                      name VARCHAR (50) 
                    );

/* 
    Create table of text logs of the games played. These are reviewed to sniff out cheating.  
*/
CREATE TABLE GameLogs ( id int IDENTITY(1,1) NOT NULL PRIMARY KEY, 
                        scoreId INT NOT NULL FOREIGN KEY REFERENCES scores(id) ON DELETE CASCADE ON UPDATE CASCADE, 
                        logText VARCHAR (8000)
                       ); 

/*
    Table of unique IP addresses that have visited the site. The 4 decimal numbers separated by dots that compose each
    IP address, e.g. the 172, 16, 254 and 1 in 172.16.254.1, correspond to the 4 columns byte1, byte2, byte3 and byte4
*/
CREATE TABLE IPs ( id int IDENTITY (1,1) NOT NULL PRIMARY KEY, 
                   byte1 tinyint, 
                   byte2 tinyint, 
                   byte3 tinyint, 
                   byte4 tinyint 
                  );

/*
     Table of banned IP addresses 
*/
CREATE TABLE BannedIPs ( id int IDENTITY (1,1) NOT NULL PRIMARY KEY, 
                         ipId int NOT NULL FOREIGN KEY REFERENCES IPs(id)
                        );

2) Right-click Migrations folder -> Add New Item -> ADO.NET Entity Data Model -> Code First from database -> (Go through the wizard to select the newly created snakedb and create the corresponding C# files)

3) Now I have in my Migrations folder new files BannedIP.cs, Configuration.cs, GameLog.cs, IP.cs, Score.cs and SnakeDB.cs

4) To a procedure to seed my database according to the instructions here, I change my Configuration.cs to

namespace SnakeGame.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using SnakeGame.Models;

    internal sealed class Configuration : DbMigrationsConfiguration<SnakeGame.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        //protected override void Seed ( SnakeGame.Migrations.SnakeDB context)
        protected void Seed (SnakeGame.Migrations.SnakeDB context)
        {

            // Test data for seeding the database

            context.IPs.AddOrUpdate(
                i => i.id,
                new IP() { id = 1, byte1 = 4, byte2 = 35, byte3 = 241, byte4 = 179 },
                new IP() { id = 2, byte1 = 172, byte2 = 16, byte3 = 254, byte4 = 1 }
            );

            context.BannedIPs.AddOrUpdate(
                i => i.id,
                new BannedIP() { id = 1, ipId = 1}
            );

            context.Scores.AddOrUpdate(
                s => s.id,
                new Score() {  id = 1, score1 = 12, name = "John Skeet" },
                new Score() {  id = 2, score1 = 1923, name = "Steve Ballmer"}
            );
        }
    }
}

5) I DROP the database snakedb because, as I understand, I will be able to recreate it and add some test data in the next step

6) I run

Add-Migration Initial
Update-Database

in the Package Manager console and get the output

Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201509300534414_Initial].
Applying explicit migration: 201509300534414_Initial.
Running Seed method.

but when I go back into SSMS, no database has been created.

Is there something I'm missing?

Also, the instructions say

The first command generates code that creates the database, and the second command executes that code. The database is created locally, using LocalDB.

and I'm wondering whether this is possible for me to do this with a remote DB as well. Is there any way to make an ASP.NET project so that publishing, rather than running the commands in the console, seeds the database?

  • 1
    Since there is no error on update-database, I assume it updated your LocalDb. Have you created a connection string for your SQL database and pointed your context at it (show context code)? Are you using a database initializer that will create the database? Also, not sure why you are creating your database in code and then turning around and reverse engineering it. The power of code first is you can design your entity classes (POCOs) and have EF create the tables and relationships for you. – Steve Greene Sep 30 '15 at 12:46
  • Hey Konald, any feedback on my answer? Cheers. – LeftyX Oct 01 '15 at 15:27

1 Answers1

0

Your database context definition should look something like this:

public class ApplicationDbContext: DbContext
{
    public ApplicationDbContext() : base("connectionString")
    {
    }

    public DbSet<Scores> Scores { get; set; }
    public DbSet<GameLogs> GameLogs { get; set; }
    public DbSet<IPs> IPs { get; set; }
    public DbSet<BannedIPs> BannedIPs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

it inherits from DbContext and defines the structure of your object model.

Your DbSet(s) should be mapped to your classes:

  • Scores
  • GameLogs
  • IPs
  • BannedIPs

As you can see the constructor needs a connection string:

public ApplicationDbContext() : base("connectionString")
{
}

which must be defined in your web.config (or app.config):

<connectionStrings>
    <add name="connectionString" connectionString="Server=localhost;Database=MigrationsTest;Trusted_Connection=True;" providerName="System.Data.SqlClient" />
</connectionStrings>

inside <configuration> section. I've used localhost here but, of course, you can use your remote database.

Now from Package Manager Console you must have enabled the migration with Enable-Migrations.
This command will build the configuration file which should look something like this:

internal sealed class Configuration : DbMigrationsConfiguration<MigratingDatabase.SchoolContext>
{
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(MigratingDatabase.SchoolContext context)
        {

        }
}

what I can see in your Configuration class it inherits from the database context:

DbMigrationsConfiguration<SnakeGame.Models.ApplicationDbContext>

but it is trying to seed a different object:

protected void Seed (SnakeGame.Migrations.SnakeDB context)
{

}

and, I guess, it should be:

protected void Seed (SnakeGame.Models.ApplicationDbContext context)
{

}

when everything is in place you can run:

Update-Database -Verbose

and it should build the database for you.

Another thing you have to do to enable the migration is change the constructor of the configuration class:

public Configuration()
{
    AutomaticMigrationsEnabled = true;
}

using AutomaticMigrationsEnabled = true.

LeftyX
  • 35,328
  • 21
  • 132
  • 193