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.
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");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With