Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignoring entities from referenced assemblies during add-migration

I have a project where my domain is split between a bunch of separate assemblies and DbContexts, all using the same underlying Sql Server database. These assemblies do not reference each other with one exception - there is one that contains what one might call shared entities, which are common to all other domains and sometimes referenced as navigational properties. Simplified example:

// Shared.dll
namespace Shared
{
   // Shared POCO
   class Hero
   {
       public string Name { get; set; }
       public string Description { get; set; }
   }

   class MyDbContext : DbContext
   {
       public virtual DbSet<Hero> Heroes { get; set; }
   } 

   internal sealed class MyDbContextConfiguration : DbMigrationsConfiguration<MyDbContext>
   {
       public MyDbContextConfiguration ()
       {
           AutomaticMigrationsEnabled = false;
           MigrationsDirectory = @"Migrations\MyDbContext";
           ContextKey = "Shared";
       }
   }
}

// Game.dll <- references Shared.dll
namespace Game
{
   // Individual POCO
   class Mission
   {
       public string Name { get; set; }
       public virtual ICollection<Hero> Protagonists { get; set; }
   }

   class MyDbContext : DbContext
   {
       public virtual DbSet<Mission> Missions { get; set; }
   } 

   internal sealed class MyDbContextConfiguration : DbMigrationsConfiguration<MyDbContext>
   {
       public MyDbContextConfiguration ()
       {
           AutomaticMigrationsEnabled = false;
           MigrationsDirectory = @"Migrations\MyDbContext";
           ContextKey = "Game";
       }
   }
}

The problem is, that when I have Hero POCO referenced in the Game.dll assembly model through ICollection<Hero> Protagonists navigational property, calling:

add-migration Test -ProjectName:Game -ConfigurationTypeName MyDbContextConfiguration -StartUpProjectName Main

ends up in creating DbMigration that includes changes for the Hero entity from the referenced Shared.dll asssembly.

    public partial class Test : DbMigration
    {
        public override void Up()
        {
            AddColumn("shared.Heroes", "Name", c => c.String());
            AddColumn("shared.Heroes", "Description", c => c.String());
            ...

How can I limit add-migration to monitoring changes only for entities located in the assembly where the DbContext has been defined? In other words, when running add-migration against Games.dll I want to ignore any changes made to entities from Shared.dll.

What could also work would be the ability to limit by namespace or database objects schema. I just don't want any changes to entities located in referenced assemblies to be included in my migrations, as all the migrations are maintained per-assembly.

like image 264
Sebastian Zaklada Avatar asked Jun 27 '16 11:06

Sebastian Zaklada


1 Answers

I have a trick for you which it easy and you can use it (by using modelBuilder.Ignore in your MyDbContext), if you are familiar with the Bounded Contexts, then this should be not something new for you:

Your DbContext:

 public class MyDbContext : DbContext
 {
   private readonly bool _isMigrationMode;

   public MyDbContext()
   {
     // This used by migration default and you can give the connection string in the command line.
     _isMigrationMode = true;
   }

   // isMigrationMode: I have give it here as an optional parameter, in case, if you want to create the migration from the code.
   public MyDbContext(string connectionString, bool isMigrationMode = false)
         : base("name=" + connectionString)
   {
     _isMigrationMode = isMigrationMode;
   }
   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
     if (_isMigrationMode)
     {
       modelBuilder.Ignore<Hero>();
     }

     base.OnModelCreating(modelBuilder);
   }

   public DbSet<Mission> Missions { get; set; }
 }

And now you can the add-migration from the command line like that:

add-migration FirstDb -ConfigurationTypeName Configuration -CONNECTIONSTRINGNAME YourConnectionString


This is the output for a similar entity which u have used in your example

 public partial class FirstDb : DbMigration
 {
     public override void Up()
     {
         CreateTable(
             "dbo.Missions",
             c => new
                 {
                     MissionId = c.Long(nullable: false, identity: true),
                     Amount = c.Int(nullable: false),
                     Amount2 = c.Int(nullable: false),
                     HeroId = c.Long(nullable: false),
                 })
             .PrimaryKey(t => t.MissionId);

     }

     public override void Down()
     {
         DropTable("dbo.Missions");
     }
 }
like image 139
Bassam Alugili Avatar answered Nov 11 '22 06:11

Bassam Alugili