原文链接:http://www.dotnet-tricks.com/Tutorial/entityframework/2VOa140214-Entity-Framework-6-Code-First-Migrations-with-Multiple-Data-Contexts.html
Entity Framework code first migrations(迁移) 允许我们基于实体来创建和更新数据库. Entity Framework5 code first migrations只能更新一个DbContext. Now, Entity Framework6 code first migrations 现在可以针对每个数据库实例更新多个DbContext。 下面我们看看在EF6中如何实现该功能.
假设你有两个 DbContext, DataContext和UserDataContext. 你需要合并这两个DataContext到一个数据库实例中.
实体模型
- public class User
- {
- public int UserID { set; get; }
- public string FirstName { set; get; }
- public string LastName { set; get; }
- }
-
- public class Role
- {
- public int RoleID { set; get; }
- public string RolesName { set; get; }
- }
-
- public class Order
- {
- public int OrderID { set; get; }
- public int Quantity { set; get; }
- public double Amount { set; get; }
- public DateTime Date { set; get; }
- }
数据库上下文
- //first DbContext
- namespace MultiDataContextMigrations.Models
- {
- public class DataContext : DbContext
- {
- public DataContext()
- : base("DefaultConnection")
- {
-
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- //TODO:Define mapping
- }
-
- public DbSet Users { get; set; }
- public DbSet Orders { get; set; }
- }
- }
- //second DbContext
- namespace MultiDataContextMigrations.Models
- {
- public class UserDataContext : DbContext
- {
- public UserDataContext():base("DefaultConnection")
- {
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- //TODO:Define mapping
- }
-
- public DbSet Users { get; set; }
- public DbSet Roles { get; set; }
- }
- }
实例1 : 一个项目中含有多个 DbContext
假设你在一个项目中含有两个DbContext,如下图:
在vs2012和vs2013的程序包管理控制台中,运行下面的命令可以分别将同一项目中的多个Dbcontex进行迁移:
- enable-migrations -ContextTypeName <DbContext-Name-with-Namespaces> -MigrationsDirectory:<Migrations-Directory-Name>
- Add-Migration -configuration <DbContext-Migrations-Configuration-Class-with-Namespaces> <Migrations-Name>
- Update-Database -configuration <DbContext-Migrations-Configuration-Class-with-Namespaces> -Verbose
迁移第一个 DbContext(DataContext)
- enable-migrations -ContextTypeName MultiDataContextMigrations.Models.DataContext -MigrationsDirectory:DataContextMigrations
- Add-Migration -configuration MultiDataContextMigrations.DataContextMigrations.Configuration Initial
- Update-Database -configuration MultiDataContextMigrations.DataContextMigrations.Configuration -Verbose
如果你在命令行执行了上面的命令,我们会看到如下的实际效果:
首先,一个迁移文件夹被创建,文件夹中有一个config类文件.
- internal sealed class Configuration : DbMigrationsConfiguration
- {
- public Configuration()
- {
- AutomaticMigrationsEnabled = false;
- //Helps to migrate this DbContext to database
- MigrationsDirectory = @"DataContextMigrations";
- }
- protected override void Seed(MultiDataContextMigrations.Models.DataContext context)
- {
- // This method will be called after migrating to the latest version.
- }
- }
第二,对应我们添加的迁移项,会生成一个类文件,显示更新的内容,本例中为创建表:
- public partial class Initial : DbMigration
- {
- public override void Up()
- {
- CreateTable(
- "dbo.Orders",
- c => new
- {
- OrderID = c.Int(nullable: false, identity: true),
- Quantity = c.Int(nullable: false),
- Amount = c.Double(nullable: false),
- Date = c.DateTime(nullable: false),
- })
- .PrimaryKey(t => t.OrderID);
-
- CreateTable(
- "dbo.Users",
- c => new
- {
- UserID = c.Int(nullable: false, identity: true),
- FirstName = c.String(),
- LastName = c.String(),
- })
- .PrimaryKey(t => t.UserID);
-
- }
-
- public override void Down()
- {
- DropTable("dbo.Users");
- DropTable("dbo.Orders");
- }
- }
第三,数据库中对应的表被生成.
迁移第二个 DbContext(DataContext)
- enable-migrations -ContextTypeName MultiDataContextMigrations.Models.UserDataContext -MigrationsDirectory:UserDataContextMigrations
- Add-Migration -configuration MultiDataContextMigrations.UserDataContextMigrations.Configuration Initial
- Update-Database -configuration MultiDataContextMigrations.UserDataContextMigrations.Configuration -Verbose
当你在程序包管理控制台窗口中执行上面命令,会有如下结果:
首先,会创建一个新的迁移文件夹和配置文件类.
- internal sealed class Configuration : DbMigrationsConfiguration
- {
- public Configuration()
- {
- AutomaticMigrationsEnabled = false;
- //Helps to migrate this DbContext to database
- MigrationsDirectory = @"UserDataContextMigrations";
- }
- protected override void Seed(MultiDataContextMigrations.Models.UserDataContext context)
- {
- // This method will be called after migrating to the latest version.
- }
- }
第二,对应我们添加的迁移项,会生成一个类文件,显示更新的内容,本例中为创建表
- public partial class Initial : DbMigration
- {
- public override void Up()
- {
- CreateTable(
- "dbo.Roles",
- c => new
- {
- RoleID = c.Int(nullable: false, identity: true),
- RolesName = c.String(),
- })
- .PrimaryKey(t => t.RoleID);
-
- CreateTable(
- "dbo.Users",
- c => new
- {
- UserID = c.Int(nullable: false, identity: true),
- FirstName = c.String(),
- LastName = c.String(),
- })
- .PrimaryKey(t => t.UserID);
-
- }
-
- public override void Down()
- {
- DropTable("dbo.Users");
- DropTable("dbo.Roles");
- }
- }
运行更新数据库命令之前,先注释掉生成user表的代码. 因为该表在上面的迁移代码中已经创建.
- public partial class Initial : DbMigration
- {
- public override void Up()
- {
- CreateTable(
- "dbo.Roles",
- c => new
- {
- RoleID = c.Int(nullable: false, identity: true),
- RolesName = c.String(),
- })
- .PrimaryKey(t => t.RoleID);
-
- //CreateTable(
- // "dbo.Users",
- // c => new
- // {
- // UserID = c.Int(nullable: false, identity: true),
- // FirstName = c.String(),
- // LastName = c.String(),
- // })
- // .PrimaryKey(t => t.UserID);
-
- }
-
- public override void Down()
- {
- DropTable("dbo.Users");
- DropTable("dbo.Roles");
- }
- }
现在运行更新命令,会在上一个Dbcontex更新命令的基础上继续更新数据库。
__MigrationHistory表
这个表是迁移历史记录。我们简单看一下.
撤销/回滚 DbContexts 迁移
你可以使用下面一些列命令,对上面两个Dbcontex的迁移更新做回滚操作.
- Update-Database -configuration MultiDataContextMigrations.DataContextMigrations.Configuration -TargetMigration:"201402141616393_Initial" -verbose
- Update-Database -configuration MultiDataContextMigrations.UserDataContextMigrations.Configuration -TargetMigration:"201402141641408_Initial" -verbose
案例 2 :不同项目中的多个Dbcontex迁移
假设,你有如下图所示的两个Dbcontex,分别在不同的项目中.
在VS2012和VS2013中,执行下面的命令可以迁移在不同项目中的多个Dbcontex到同一数据库实例:
Syntax - EF Code First Migrations with Multiple DbContexts within different Projects
- enable-migrations -ProjectName:<ProjectName> -MigrationsDirectory:<Migrations-Directory-Name>
- add-migration <Migrations-Name> -ProjectName:<ProjectName>
- update-database -ProjectName:<ProjectName> -verbose
迁移第一个DbContext(DataContext)
- //migrating DataContext
- enable-migrations -ProjectName:DAL -MigrationsDirectory:DataContextMigrations
- add-migration InitialCreate -ProjectName:DAL
- update-database -ProjectName:DAL -verbose
迁移第二个DbContext(UserDataContext)
- //migrating UserDataContext
- enable-migrations -ProjectName:MultiDataContextMigrations -MigrationsDirectory:UserDataContextMigrations
- add-migration InitialCreate -ProjectName:MultiDataContextMigrations
- update-database -ProjectName:MultiDataContextMigrations -verbose
撤销/回滚DbContexts Migrations
- update-database -ProjectName:DAL -TargetMigration:"201401290826231_InitialCreate" -verbose
- update-database -ProjectName:MultiDataContextMigrations -TargetMigration:"201401290836540_InitialCreate" -verbose