4

I was on a Spike branch, playing around with EF Migrations and once I got what I wanted, created the actual dev branch from scratch (based on a previous branch that does not have any DB or ORM related code at all).

The new code

I have a context that inherits from DbContext with this DbSet:

public DbSet<Warehouse> Warehouses { get; set; }

And Warehouse contains this:

public class Warehouse
{
    public string Code { get; set; }
    public string Name { get; set; }
}

Migrations

If I run

add-migration Warehouse

I get a file called 201708040819010_Warehouse.cs, which contains this:

public override void Up()
{
    RenameTable(name: "dbo.Warehouses", newName: "Warehouse");
    DropPrimaryKey("dbo.Warehouse");
    AddColumn("dbo.Warehouse", "Code", c => c.String(nullable: false, maxLength: 128));
    AlterColumn("dbo.Warehouse", "Name", c => c.String(maxLength: 100));
    AddPrimaryKey("dbo.Warehouse", "Code");
    CreateIndex("dbo.Warehouse", "Name", unique: true);
    DropColumn("dbo.Warehouse", "Id");
    DropColumn("dbo.Warehouse", "Abbreviation");
    DropTable("dbo.People");
}

Which is not at all what I expected.

What's wrong

All those renames, alter column and drop columns seem to suggest that somehow Migrations is convinced that it needs to update an existing table in an existing db.

But that's not true, because I removed my old localdb, am working on a completely new branch and on a new migration.

Not completely out of the blue

I did however have a Warehouse class (when playing around in that Spike branch) that contained an Id, Name and Abbreviation.

But that's old news. And doesn't physically exist anymore.

What I suspect is going on

Is that Visual Studio is tripping over itself and is basing the new Migrations on information that is stored in it's temporary folders. I did a clean of what looked like it could be related based on this post, but to no positive effect.

Update

DbContext

public class MyDbContext : DbContext, IMyDbContext
{
    public MyDbContext()
        :base("MyDb")
    {
        Configuration.LazyLoadingEnabled = false;
        Database.SetInitializer(new NullDatabaseInitializer<MyDbContext>());
    }

    public DbSet<Warehouse> Warehouses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations
            .AddFromAssembly(Assembly.GetExecutingAssembly());

        modelBuilder.Conventions
            .AddFromAssembly(Assembly.GetExecutingAssembly());
    }
}

EF Migrations config

internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(MyDbContext context)
    {
    }
}

Question

What can I do to fix this (weird) behaviour?

Spikee
  • 3,967
  • 7
  • 35
  • 68
  • Are you generating your migrations against another database? As the data to generate a migration is stored inside of the database its self in the migration history table. – Darren Aug 04 '17 at 08:57
  • 1
    @Darren: It's the same connstring, pointing to a localdb that I removed earlier. (I tried chosing a different catalog name, no difference) – Spikee Aug 04 '17 at 08:59
  • 1
    Could you post your DbContext class & your EF migration configuration. – Darren Aug 04 '17 at 09:11
  • 1
    @Darren: Added. – Spikee Aug 04 '17 at 09:17
  • 1
    Right could you compare what c# exists in your migration folder with what exists in your _migrationhistory table in your database and make sure you have all the migrations in your database and code. – Darren Aug 04 '17 at 09:39

1 Answers1

2

I found it. The cause was this:

enter image description here

I didn't notice this before because you only see it when you use -verbose on update-database. Which I don't do unless something's not working (like now).

And the reason behind this is that to run, you need to have a startup project, which in my case is my REST API. As it doesn't have a connectionstring (yet, on purpose), rather than giving an error, Migrations assumes that I want to use my .\SQLEXPRESS instance.

Since I didn't provide a connectionstring on my Spike either, I was working on SQLEXPRESS without noticing, and was now checking against the old table definition, causing these renames and drops instead of a clean create.

... quite the (annoying) assumption. I would have preferred an error.

Spikee
  • 3,967
  • 7
  • 35
  • 68