NetCore下使用EFCore CodeFirst 方式创建更新数据库
项目结构图如下:
IService 主要是接口 ,Service 是服务处理,Models 各种数据实体,Repository 数据访问处理
1、首先在Models 项目下创建类
1 namespace Models 2 { 3 [Table("User")] 4 public class BaseUser 5 { 6 [Key] 7 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 8 public int Id { get; set; } 9 [MaxLength(20)] 10 public string UserName { get; set; } 11 } 12 }
1 namespace Models 2 { 3 [Table("Role")] 4 public class Role 5 { 6 [Key] 7 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 8 public int Id { get; set; } 9 [MaxLength(20)] 10 [Required] 11 public string RoleName { get; set; } 12 13 } 14 }
1 namespace Models 2 { 3 [Table("UserRole")] 4 public class UserRole 5 { 6 [Key] 7 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 8 public int Id { get; set; } 9 [ForeignKey("UserID")] 10 public virtual BaseUser User { get; set; } 11 [ForeignKey("RoleID")] 12 public virtual Role Role { get; set; } 13 14 } 15 }
2、在 Repository 项目下创建DbContext类
1 namespace Repository 2 { 3 public partial class MiveDb:DbContext 4 { 5 public MiveDb() 6 { 7 8 } 9 10 public MiveDb(DbContextOptions<MiveDb> options) 11 :base(options) 12 { 13 14 } 15 16 protected override void OnModelCreating(ModelBuilder modelBuilder) 17 { 18 base.OnModelCreating(modelBuilder); 19 } 20 21 public virtual DbSet<Movie> Movie { get; set; } 22 public virtual DbSet<BaseUser> User { get; set; } 23 public virtual DbSet<Role> Role { get; set; } 24 public virtual DbSet<UserRole> UserRole { get; set; } 25 } 26 }
3、在Web项目下的appsettings.json文件中添加数据库连接字符串,添加后如下:
1 { 2 "Logging": { 3 "LogLevel": { 4 "Default": "Warning" 5 } 6 }, 7 "AllowedHosts": "*", 8 "ConnectionStrings": { 9 "DefaultConnection": "Data Source=127.0.0.1;Initial Catalog=MovieDb;user id=sa;password=sa@123;Max Pool Size=512;Min Pool Size=5" 10 } 11 }
4、在webapp 配置 Startup.cs 下进行配置
4.1 创建一个方法用于程序集注入
1 /// <summary> 2 /// 自动注册服务——获取程序集中的实现类对应的多个接口 3 /// </summary> 4 /// <param name="services">服务集合</param> 5 /// <param name="assemblyName">程序集名称</param> 6 public void AddAssembly(IServiceCollection services, string assemblyName) 7 { 8 if (!String.IsNullOrEmpty(assemblyName)) 9 { 10 Assembly assembly = Assembly.Load(assemblyName); 11 List<Type> ts = assembly.GetTypes().Where(u => u.IsClass && !u.IsAbstract && !u.IsGenericType).ToList(); 12 foreach (var item in ts.Where(s => !s.IsInterface)) 13 { 14 var interfaceType = item.GetInterfaces(); 15 if (interfaceType.Length == 1) 16 { 17 services.AddTransient(interfaceType[0], item); 18 } 19 if (interfaceType.Length > 1) 20 { 21 services.AddTransient(interfaceType[1], item); 22 } 23 } 24 } 25 } 26
4.2 在 Startup.cs 中 ConfigureServices 方法中添加注入
1 AddAssembly(services, "IService"); 2 AddAssembly(services, "Service"); 3 services.AddDbContext<MiveDb>(options => 4 { 5 var connection = Configuration.GetConnectionString("DefaultConnection"); 6 options.UseSqlServer( 7 connection 8 ); 9 });
4.3 按照项目需要,引用个项目
5、打开命令行控制台,切换到 Repository 项目
PM> Add-Migration FirstMigration
执行以上命令,备注:
FirstMigration 名字任意取
中间可能会遇见各种问题,主要是各个项目之间的引用就可以解决
执行成功后,Repository 中会出现 如图
但是发现在TestMovieDB.cs这个文件中有一个错误
SqlServerValueGenerationStrategy 缺少引用
1 namespace Repository.Migrations 2 { 3 public partial class TestMovieDB : Migration 4 { 5 protected override void Up(MigrationBuilder migrationBuilder) 6 { 7 migrationBuilder.CreateTable( 8 name: "Movie", 9 columns: table => new 10 { 11 Id = table.Column<int>(nullable: false) 12 .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 13 Title = table.Column<string>(maxLength: 50, nullable: true), 14 Info = table.Column<string>(maxLength: 500, nullable: true), 15 CreateTime = table.Column<DateTime>(nullable: false) 16 }, 17 constraints: table => 18 { 19 table.PrimaryKey("PK_Movie", x => x.Id); 20 }); 21 22 migrationBuilder.CreateTable( 23 name: "Role", 24 columns: table => new 25 { 26 Id = table.Column<int>(nullable: false) 27 .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 28 RoleName = table.Column<string>(maxLength: 20, nullable: false) 29 }, 30 constraints: table => 31 { 32 table.PrimaryKey("PK_Role", x => x.Id); 33 }); 34 35 migrationBuilder.CreateTable( 36 name: "User", 37 columns: table => new 38 { 39 Id = table.Column<int>(nullable: false) 40 .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 41 UserName = table.Column<string>(maxLength: 20, nullable: true) 42 }, 43 constraints: table => 44 { 45 table.PrimaryKey("PK_User", x => x.Id); 46 }); 47 48 migrationBuilder.CreateTable( 49 name: "UserRole", 50 columns: table => new 51 { 52 Id = table.Column<int>(nullable: false) 53 .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 54 UserID = table.Column<int>(nullable: true), 55 RoleID = table.Column<int>(nullable: true) 56 }, 57 constraints: table => 58 { 59 table.PrimaryKey("PK_UserRole", x => x.Id); 60 table.ForeignKey( 61 name: "FK_UserRole_Role_RoleID", 62 column: x => x.RoleID, 63 principalTable: "Role", 64 principalColumn: "Id", 65 onDelete: ReferentialAction.Restrict); 66 table.ForeignKey( 67 name: "FK_UserRole_User_UserID", 68 column: x => x.UserID, 69 principalTable: "User", 70 principalColumn: "Id", 71 onDelete: ReferentialAction.Restrict); 72 }); 73 74 migrationBuilder.CreateIndex( 75 name: "IX_UserRole_RoleID", 76 table: "UserRole", 77 column: "RoleID"); 78 79 migrationBuilder.CreateIndex( 80 name: "IX_UserRole_UserID", 81 table: "UserRole", 82 column: "UserID"); 83 } 84 85 protected override void Down(MigrationBuilder migrationBuilder) 86 { 87 migrationBuilder.DropTable( 88 name: "Movie"); 89 90 migrationBuilder.DropTable( 91 name: "UserRole"); 92 93 migrationBuilder.DropTable( 94 name: "Role"); 95 96 migrationBuilder.DropTable( 97 name: "User"); 98 } 99 } 100 }
哈哈,没关系,这个问题明显是缺少 对dll 的引用,我们引用即可
接着引用 Microsoft.EntityFrameworkCore.SqlServer dll,版本根据实际需求引用
这个时候虽然成功了,但是数据库中的数据还未被创建
6、执行数据库更新操作
1 PM> Update-Database -Verbose
出现这些就表示成功了,接着我们看数据库
此时数据库已经创建好了!
7、有没有发现数据库的名称和我们DbContext 名字一样
具体啥原因没仔细研究