1- 启动项目
安装.NETCORE SDK,教程在网上可以搜索的到,这里就不讲述了。简单粗暴的方式就是安装最新的VS2015.
2-搭建框架
2.1 打开VS新建一个项目,在弹出的新建项目对话框中,选中NET CORE选项,右边出现的选项就是.NET CORE的所有可建项目了。然后和创建传统.NET项目一样的创建项目就行了。
PS:不理解的可以参考 园子里面翻译小组的文章
2.2 开始编写领域实体对象。这里是先实现一个简单的权限管理。所以现在GR.Core 类库中创建一个domain文件夹,然后分别创建 User,Role,Menu实体,以及一个实体基类。
2.2.1 User 实体类:暂时只有用户名/密码/是否激活字段 (由于使用的是一个用户有多个角色的思路,因此多了一个List<UserRole> 导航属性,所以实体都是继承自baseEntity)
1 public class User : BaseEntity 2 { 3 public string UserName { get; set; } 4 5 public string Password { get; set; } 6 7 public bool IsActived { get; set; } 8 9 public List<UserRole> UserRoles { get; set; } 10 }
2.2.2 Role 实体类:
1 public class Role : BaseEntity 2 { 3 public string RoleName { get; set; } 4 5 public bool IsActived { get; set; } 6 7 }
2.2.3 Menu实体类:因为用的MVC 所以我没有使用URL那个字段,而是用areaname,contollername,actionname着三个字段,我想实现的是可以直接通过actionname去判断该用户是否用增删改查的权限。暂时没有想的很细,所以后续可能会改动。
1 public class Menu : BaseEntity 2 { 3 public int? ParentId { get; set; } 4 5 public string MenuName { get; set; } 6 7 public string AreaName { get; set; } 8 9 public string ControllerName { get; set; } 10 11 public string ActionName { get; set; } 12 13 public bool IsActived { get; set; } 14 15 public Menu Parent { get; set; } 16 17 public List<Menu> Children { get; set; } 18 19 public List<MenuRole> MenuRoles { get; set; } 20 }
2.2.4 UserRole,MenuRole实体:由于没有了map(m=>{}) 这个直接映射中间表的API,所以我们需要创建中间实体,来生成数据库中间表。
1 public class UserRole 2 { 3 public int UserId { get; set; } 4 5 public int RoleId { get; set; } 6 7 public User User { get; set; } 8 9 public Role Role { get; set; } 10 }
1 public class MenuRole 2 { 3 public int MenuId { get; set; } 4 5 public int RoleId { get; set; } 6 7 public Menu Menu { get; set; } 8 9 public Role Role { get; set; } 10 }
2.2.5 小结
到此关于权限相关的实体类都创建完成了。接下来我们需要做的就是开始映射,然后生成数据库。
2.3 实体映射并生成数据库
2.3.1 在GR.Data的project.json文件中添加GR.Core项目引用,以及entityframecore的相关引用
2.3.2 创建Mapping文件夹,然后创建各个实体映射。
fluent api EntityTypeConfiguration<XXX> 已经取消了,改成使用ModelBuilder来做实体映射,映射函数名称都一样,就是移除了多对多关系的映射(所以前面创建实体类的时候有说需要创建中间实体类)。
1 public class MenuMap 2 { 3 public static void Map(ModelBuilder modelBuilder) 4 { 5 //表映射 6 modelBuilder.Entity<Menu>().ToTable("Menu"); 7 //主键映射 8 modelBuilder.Entity<Menu>().HasKey(t => t.Id).HasName("PK_MENU_ID"); 9 //列映射 10 modelBuilder.Entity<Menu>().Property(t => t.Id).HasColumnName("Id"); 11 modelBuilder.Entity<Menu>().Property(t => t.ParentId).HasColumnName("ParentId"); 12 modelBuilder.Entity<Menu>().Property(t => t.MenuName).IsRequired().HasColumnName("MenuName").HasColumnType("nvarchar(100)"); 13 modelBuilder.Entity<Menu>().Property(t => t.AreaName).HasColumnName("AreaName").HasColumnType("nvarchar(100)"); 14 modelBuilder.Entity<Menu>().Property(t => t.ControllerName).HasColumnName("ControllerName").HasColumnType("nvarchar(100)"); 15 modelBuilder.Entity<Menu>().Property(t => t.ActionName).HasColumnName("ActionName").HasColumnType("nvarchar(500)"); 16 modelBuilder.Entity<Menu>().Property(t => t.IsActived).HasColumnName("IsActived"); 17 //关系映射 18 modelBuilder.Entity<Menu>() 19 .HasOne(t => t.Parent) 20 .WithMany(t => t.Children) 21 .HasForeignKey(t => t.ParentId) 22 .HasConstraintName("FK_PARENT_CHILDREN_PARENTID"); 23 24 } 25 }
modelBuilder.Entity<Menu>().HasKey(t => t.Id).HasName("PK_MENU_ID"); 这里的hasname表示可以自定义主键的名称
1 public class MenuRoleMap 2 { 3 public static void Map(ModelBuilder modelBuilder) 4 { 5 //表映射 6 modelBuilder.Entity<MenuRole>().ToTable("MenuRoleMapping"); 7 //主键映射 8 modelBuilder.Entity<MenuRole>().HasKey(t => new { t.RoleId, t.MenuId }).HasName("PK_MENU_ROLE_MENUROLEID"); 9 //列映射 10 modelBuilder.Entity<MenuRole>().Property(t => t.RoleId).HasColumnName("RoleId"); 11 modelBuilder.Entity<MenuRole>().Property(t => t.MenuId).HasColumnName("MenuId"); 12 //关系映射 13 modelBuilder.Entity<MenuRole>().HasOne(t => t.Menu).WithMany(t => t.MenuRoles).HasForeignKey(t => t.MenuId).HasConstraintName("FK_MENU_ROLE_MENUID"); 14 15 } 16 }
其他的实体类映射方式都一样
2.3.3 接下来我们来创建一个 Dbcontext类
1 using System; 2 using GR.Core.Domain; 3 using GR.Core.Domain.Menus; 4 using GR.Core.Domain.Roles; 5 using GR.Core.Domain.Users; 6 using GR.Data.Mapping.Menus; 7 using GR.Data.Mapping.Roles; 8 using GR.Data.Mapping.Users; 9 using Microsoft.EntityFrameworkCore; 10 11 namespace GR.Data 12 { 13 /// <summary> 14 /// 数据库链接上下文 15 /// </summary> 16 public class GRDbContext : DbContext 17 { 18 //public GRDbContext(DbContextOptions options) : base(options) 19 //{ 20 //} 21 22 //protected GRDbContext() : base() 23 //{ 24 25 //} 26 27 public DbSet<User> Users { get; set; } 28 public DbSet<Role> Roles { get; set; } 29 public DbSet<Menu> Menus { get; set; } 30 public DbSet<UserRole> UserRoles { get; set; } 31 public DbSet<MenuRole> MenuRoles { get; set; } 32 33 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 34 { 35 optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=NetCoreDb;Integrated Security=False;Persist Security Info=False;User ID=sa;Password=Passw0rd"); 36 base.OnConfiguring(optionsBuilder); 37 } 38 39 protected override void OnModelCreating(ModelBuilder modelBuilder) 40 { 41 TableMap(modelBuilder); 42 // 43 base.OnModelCreating(modelBuilder); 44 } 45 46 /// <summary> 47 /// 表结构映射 48 /// </summary> 49 /// <param name="modelBuilder"></param> 50 protected void TableMap(ModelBuilder modelBuilder) 51 { 52 UserMap.Map(modelBuilder); 53 RoleMap.Map(modelBuilder); 54 MenuMap.Map(modelBuilder); 55 UserRoleMap.Map(modelBuilder); 56 MenuRoleMap.Map(modelBuilder); 57 } 58 59 /// <summary> 60 /// Get DbSet 61 /// </summary> 62 /// <typeparam name="TEntity">Entity type</typeparam> 63 /// <returns>DbSet</returns> 64 public new DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity 65 { 66 return base.Set<TEntity>(); 67 } 68 69 } 70 }
optionsbuilder.UserSqlServer:这个是创建数据库连接函数,这个可以在web项目中的startup类中就行配置。
在startup中配置,需要提供 public GRDbContext(DbContextOptions options) : base(options) 这个构造函数
2.3.4 下面我们就可以开始 生成数据库了
打开 nuget控制台,默认项目选择GR.Data,因为NETCORE已经取消了enable-migration,因此我们直接输入Add-Migration CreateInit 命令就可以了,然后使用update-database命令就可以生成数据库了。当你觉得Add-Migration生成的文件有问题或者不需要可以使用remove-Migration 命令删除该文件
3-小结
到此 搭建框架,生成数据库 的工作就完成了,明天我们将实现UI框架搭建以及登录功能。
PS:项目已经开源在Github,不过没有完成,后续将慢慢完善,欢迎大家提建议。