Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

NuoDB Support for Entity Framework Code First Migrations

DZone's Guide to

NuoDB Support for Entity Framework Code First Migrations

· Java Zone
Free Resource

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

As Entity Framework simplifies working with data – and I mean basic operations like querying and updating – there’s also of course demand to simplify other parts of an application developer’s life. The data needs to be stored somewhere. Somewhere in a database with structure that, preferably, matches your Entity Framework model and classes!

Code First Migrations is the part of Entity Framework that makes it easier to manage the structure of a database as an application evolves over time. You don’t have to deal with DDL commands and so on; you just let the logic update your database to the current state of the model. And, of course, you can change the result before it’s applied and even add elements as you see fit, such as indexes.

(In the example that follows, I’ll outline a simple example of how to work with Migrations. Visit MSDN if you need help getting started with Entity Framework.)

If you install (or update) a freshly-released Entity Framework driver for NuoDB from NuGet by invoking the Tools | NuGet Package Manager | Package Manager Console and issuing the command Install-Package EntityFramework.NuoDb you’ll be ready to go.

Install Entity Framework

Let’s start with a simplified Entity Framework model, similar to the “Hockey” example:

class HockeyContext : DbContext
{
       public HockeyContext()
              : base(new NuoDbConnection(Config.ConnectionString), true)
       { }
 
       protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {
              base.OnModelCreating(modelBuilder);
 
              modelBuilder.HasDefaultSchema("migrations");
 
              var playerConf = modelBuilder.Entity<[Player]>();
              playerConf.ToTable("PLAYERS");
       }
 
       public DbSet<[Player]> Players { get; set; }
}
 
class Player
{
       public string PlayerId { get; set; }
       public string FirstName { get; set; }
       public string LastName { get; set; }
}

The next step is to enable Migrations using the Enable-Migrations cmdlet, where I’ll use the supplied defaults. This step will create a new folder in the project, with a configuration file inside.

Enable-Migrations.png

Then I add a first migration using Add-Migration Initial (using, in this case, the name “Initial”). This creates a class with the same name, capturing the current state of the model:

public partial class Initial : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "migrations.PLAYERS",
            c => new
                {
                    PlayerId = c.String(nullable: false, maxLength: 128, unicode: false),
                    FirstName = c.String(unicode: false),
                    LastName = c.String(unicode: false),
                })
            .PrimaryKey(t => t.PlayerId);
    }
 
    public override void Down()
    {
        DropTable("migrations.PLAYERS");
    }
}

First-Migration.png

This looks like C# code, but it’s not meant to be executed; it only helps to capture the migration steps, which will be translated to SQL for NuoDB using Update-Database -Script. This will open a new document containing the SQL that should be executed on the database in order to set up the tables corresponding to our data model:

CREATE TABLE "migrations"."PLAYERS" (
       "PlayerId" VARCHAR(128) NOT NULL,
       "FirstName" VARCHAR(32765),
       "LastName" VARCHAR(32765)
)
;
 
ALTER TABLE "migrations"."PLAYERS" ADD CONSTRAINT "PK_migrations_PLAYERS" PRIMARY KEY ("PlayerId")
;
 
CREATE TABLE "migrations"."__MigrationHistory" (
       "MigrationId" VARCHAR(150) NOT NULL,
       "ContextKey" VARCHAR(300) NOT NULL,
       "Model" BLOB NOT NULL,
       "ProductVersion" VARCHAR(32) NOT NULL
)
;
 
ALTER TABLE "migrations"."__MigrationHistory" ADD CONSTRAINT "PK_migrations___MigrationHistory" PRIMARY KEY ("MigrationId", "ContextKey")
;
 
INSERT INTO "migrations"."__MigrationHistory"("MigrationId", "ContextKey", "Model", "ProductVersion")
VALUES ('201409211350349_Initial', 'NuoDbMigrationsTest.Migrations.Configuration', 0x1F8B0...0D0000, '6.1.1-30610')

Update-Database.png

This is a fairly typical SQL script based on our simple model. You can also make the framework apply the changes on your behalf by removing the -Script option and just invoking Update-Database.

Let’s add a new column and index it using CreateIndex:

public partial class Index : DbMigration
{
    public override void Up()
    {
        AddColumn("migrations.PLAYERS", "Snafu", c => c.Int(nullable: false));
        CreateIndex("migrations.PLAYERS", "Snafu", unique: false, name: "IDX_PLAYERS_Snafu");
    }
 
    public override void Down()
    {
        DropColumn("migrations.PLAYERS", "Snafu");
    }
}

Here’s the resulting script:

ALTER TABLE "migrations"."PLAYERS" ADD "Snafu" INT NOT NULL DEFAULT 0;
 
CREATE INDEX "IDX_PLAYERS_Snafu" ON "migrations"."PLAYERS"("Snafu");
 
INSERT INTO "migrations"."__MigrationHistory"("MigrationId", "ContextKey", "Model", "ProductVersion")
VALUES ('201409211407156_Index', 'NuoDbMigrationsTest.Migrations.Configuration', 0x1F8B0800...8730F0000, '6.1.1-30610');

The magic behind this is in the “NuoDbMigrationSqlGenerator” class. You can derive your own if you’d like, to change the generated SQL. You’ll have to tell Entity Framework in the “DbConfiguration” derived class to use it, via the “SetMigrationSqlGenerator” method.

Easy, right? I hope you’ll enjoy this new Code First Migrations chapter in the Entity Framework story.  Give NuoDB and Entity Framework a spin.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Paul Lothridge. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}