《一步一步使用ABP框架搭建正式项目系列教程》

这一节我们说说数据库迁移(Migration)。

我们之前用的DBFirst创建了实体类,但当初这么做的原因是为了节省时间。现在我们通过创建的实体类和DbContext类利用EF的Code First数据库迁移反过来创建数据库。ABP模板默认开启了迁移,并且添加了一下下面的Configuration类:

 1 using EntityFramework.DynamicFilters;
 2 using System.Data.Entity.Migrations;
 3 using Witcare.PSS.Migrations.SeedData;
 4 
 5 namespace Witcare.PSS.Migrations
 6 {
 7     internal sealed class Configuration : DbMigrationsConfiguration<PSS.EntityFramework.PSSDbContext>
 8     {
 9         public Configuration()
10         {
11             AutomaticMigrationsEnabled = false;
12             ContextKey = "PSS";
13         }
14         /// <summary>
15         /// 添加种子数据,比如默认管理员等数据
16         /// </summary>
17         /// <param name="context">当前数据库上下文子类</param>
18         protected override void Seed(PSS.EntityFramework.PSSDbContext context)
19         {
20             context.DisableAllFilters();
21             new InitialDataBuilder(context).Build();
22         }
23     }
24 }
  1 using System.Linq;
  2 using Abp.Authorization;
  3 using Abp.Authorization.Roles;
  4 using Abp.Authorization.Users;
  5 using Abp.MultiTenancy;
  6 using Witcare.PSS.Authorization;
  7 using Witcare.PSS.Authorization.Roles;
  8 using Witcare.PSS.EntityFramework;
  9 using Witcare.PSS.MultiTenancy;
 10 using Witcare.PSS.Users;
 11 using Microsoft.AspNet.Identity;
 12 
 13 namespace Witcare.PSS.Migrations.SeedData
 14 {
 15     public class DefaultTenantRoleAndUserBuilder
 16     {
 17         private readonly PSSDbContext _context;
 18 
 19         public DefaultTenantRoleAndUserBuilder(PSSDbContext context)
 20         {
 21             _context = context;
 22         }
 23 
 24         public void Build()
 25         {
 26             CreateUserAndRoles();
 27         }
 28 
 29         private void CreateUserAndRoles()
 30         {
 31             //Admin role for host
 32 
 33             var adminRoleForHost = _context.Roles.FirstOrDefault(r => r.TenantId == null && r.Name == StaticRoleNames.Host.Admin);
 34             if (adminRoleForHost == null)
 35             {
 36                 adminRoleForHost = _context.Roles.Add(new Role { Name = StaticRoleNames.Host.Admin, DisplayName = StaticRoleNames.Host.Admin, IsStatic = true });
 37                 _context.SaveChanges();
 38 
 39                 //Grant all tenant permissions
 40                 var permissions = PermissionFinder
 41                     .GetAllPermissions(new PSSAuthorizationProvider())
 42                     .Where(p => p.MultiTenancySides.HasFlag(MultiTenancySides.Host))
 43                     .ToList();
 44 
 45                 foreach (var permission in permissions)
 46                 {
 47                     if (!permission.IsGrantedByDefault)
 48                     {
 49                         _context.Permissions.Add(
 50                             new RolePermissionSetting
 51                             {
 52                                 Name = permission.Name,
 53                                 IsGranted = true,
 54                                 RoleId = adminRoleForHost.Id
 55                             });
 56                     }
 57                 }
 58 
 59                 _context.SaveChanges();
 60             }
 61 
 62             //Admin user for tenancy host
 63 
 64             var adminUserForHost = _context.Users.FirstOrDefault(u => u.TenantId == null && u.UserName == User.AdminUserName);
 65             if (adminUserForHost == null)
 66             {
 67                 adminUserForHost = _context.Users.Add(
 68                     new User
 69                     {
 70                         TenantId = null,
 71                         UserName = User.AdminUserName,
 72                         Name = "System",
 73                         Surname = "Administrator",
 74                         EmailAddress = "admin@aspnetboilerplate.com",
 75                         IsEmailConfirmed = true,
 76                         Password = new PasswordHasher().HashPassword(User.DefaultPassword)
 77                     });
 78 
 79                 _context.SaveChanges();
 80 
 81                 _context.UserRoles.Add(new UserRole(adminUserForHost.Id, adminRoleForHost.Id));
 82 
 83                 _context.SaveChanges();
 84             }
 85 
 86             //Default tenant
 87 
 88             var defaultTenant = _context.Tenants.FirstOrDefault(t => t.TenancyName == "Default");
 89             if (defaultTenant == null)
 90             {
 91                 defaultTenant = _context.Tenants.Add(new Tenant { TenancyName = "Default", Name = "Default" });
 92                 _context.SaveChanges();
 93             }
 94 
 95             //Admin role for 'Default' tenant
 96 
 97             var adminRoleForDefaultTenant = _context.Roles.FirstOrDefault(r => r.TenantId == defaultTenant.Id && r.Name == StaticRoleNames.Tenants.Admin);
 98             if (adminRoleForDefaultTenant == null)
 99             {
100                 adminRoleForDefaultTenant = _context.Roles.Add(new Role { TenantId = defaultTenant.Id, Name = StaticRoleNames.Tenants.Admin, DisplayName = StaticRoleNames.Tenants.Admin, IsStatic = true });
101                 _context.SaveChanges();
102 
103                 //Grant all tenant permissions
104                 var permissions = PermissionFinder
105                     .GetAllPermissions(new PSSAuthorizationProvider())
106                     .Where(p => p.MultiTenancySides.HasFlag(MultiTenancySides.Tenant))
107                     .ToList();
108 
109                 foreach (var permission in permissions)
110                 {
111                     if (!permission.IsGrantedByDefault)
112                     {
113                         _context.Permissions.Add(
114                             new RolePermissionSetting
115                             {
116                                 Name = permission.Name,
117                                 IsGranted = true,
118                                 RoleId = adminRoleForDefaultTenant.Id
119                             });
120                     }
121                 }
122 
123                 _context.SaveChanges();
124             }
125 
126             //Admin for 'Default' tenant
127 
128             var adminUserForDefaultTenant = _context.Users.FirstOrDefault(u => u.TenantId == defaultTenant.Id && u.UserName == User.AdminUserName);
129             if (adminUserForDefaultTenant == null)
130             {
131                 adminUserForDefaultTenant = _context.Users.Add(
132                     new User
133                     {
134                         TenantId = defaultTenant.Id,
135                         UserName = User.AdminUserName,
136                         Name = "System",
137                         Surname = "Administrator",
138                         EmailAddress = "admin@aspnetboilerplate.com",
139                         IsEmailConfirmed = true,
140                         Password = new PasswordHasher().HashPassword(User.DefaultPassword)
141                     });
142                 _context.SaveChanges();
143 
144                 _context.UserRoles.Add(new UserRole(adminUserForDefaultTenant.Id, adminRoleForDefaultTenant.Id));
145                 _context.SaveChanges();
146             }
147         }
148     }
149 }

在Seed方法中,添加了租户,角色和用户数据。现在,我来创建初始化迁移。打开包管理器控制台,输入下面的命令:

此处特别注意,红色方框中一定不要忘了选择EF项目,否则不会有下面出现的命令“Add-Migration”,”InitialData”是生成文件的后缀名(也是文件中类的名字),也可以取其他名字。

可以看到生成的文件一个以cs结尾,这里面的代码是创建数据库中表的,另一个以Designer.cs结尾,记录的是数据库迁移的版本记录,最后一个以.resx文件是资源文件,暂且不需要考虑。

刚才我们只是创建了创建数据库所需要的类,但还没有创建数据库。为了创建数据库,需要在包管理控制台执行以下命令:

PM> Update-Database  这边要记得:一定要把web设为启动项目
 

该命令完成了这次数据库的迁移,创建了数据库并填充了种子数据。

当我们改变实体类时,可以使用Add-Migration命令创建新的迁移类和Update-Database命令更新数据库。

至此,数据库迁移完成。下一次我们说说《定义仓储》。

posted @ 2016-04-21 11:43  MillerShi  阅读(9402)  评论(0编辑  收藏  举报