asp.net core经过ef core来访问数据库,这里用的是代码优先,经过迁移来同步数据库与模型。web
环境:vs2017,win10,asp.net core 2.1sql
1、从创建asp.net core web项目开始 数据库
一、经过vs2017创建一个asp.net core web应用程序json
二、在models文件夹下面建立一个student类,这个类用做数据模型,表示的是数据库里面的student表 windows
public class Student { [DatabaseGenerated(DatabaseGeneratedOption.None)] public Guid ID { set; get; } [Required] [MaxLength(30)] public string Name { set; get; } public int Age { set; get; } public byte Sex { set; get; } public string Remark { set; get; } [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreateDate { set; get; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime LastUpdate { set; get; } }
关于表里面的特性说明这里暂时无论,等建立了数据库后再来讲明。mvc
三、建立数据库上下文app
在项目中创建一个Data文件夹,建立一个类SqlServerContextasp.net
public class SqlServerContext : DbContext { public SqlServerContext(DbContextOptions<SqlServerContext> options) : base(options) { } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>().ToTable("Student"); } }
在 Entity Framework 中,实体集一般与数据表相对应,具体实体与表中的行相对应。当数据库建立完成后, EF 建立一系列数据表,表名默认和 DbSet
属性名相同。但能够在OnModelCreating方法中指定表名。ide
四、注册数据库上下文工具
打开 Startup.cs,在ConfigureServices方法中添加以下代码
services.AddDbContext<SqlServerContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SqlServerContext")));
SqlServerContext是数据库字符串的名称。打开appsettings.json 文件,并如如下示例所示添加链接字符串。
"ConnectionStrings": { "SqlServerContext": "Server=(localdb)\\ProjectsV84;Database=TestDB1;Trusted_Connection=True;MultipleActiveResultSets=true" }
这里链接的是本地数据库,数据库的验证方式是windows验证。
五、迁移
经过命令行接口 (CLI)执行迁移命令来实现迁移,在此以前,须要按照适用于命令行接口 (CLI) 的 EF 工具。 注意: 必须经过编辑 .csproj 文件来安装此包;不能使用 install-package
命令或包管理器 GUI。
若要编辑 .csproj 文件,可右键单击解决方案资源管理器中的项目名称,而后选择“编辑EFCoreDB.csproj”,在ItemGroup里面添加以下代码
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
在项目所在的文件夹下打开cmd窗口,执行命令:dotnet ef migrations add CreateDB
命令执行成功的话,会在项目中添加一个文件夹Migrations
这里面的两个文件就是EF如何建立数据库的,通常来讲不须要手动去修改这两个文件。
这时候,数据库里面尚未相应的数据库和表
在cmd中执行命令dotnet ef database update,成功执行后,就能够在数据库里面看到建立的数据库和表了
六、分析
如今来看看student表的列和模型student的关系
系统默认ID是主键,这是一种约定,固然也能够在模型student的ID属性上用 [
模型中,ID的类型是guid,在数据库里面就对应类型uniqueidentifier,[DatabaseGenerated(DatabaseGeneratedOption.None)]特性表示ID列不须要数据库自动添加值。
Name和Remark都是string类型,remark没有任何修饰,因此数据库中的类型就是nvarchar(max),且能够为空。
七、步骤优化
上面的的6个步骤中,第3,4两步能够不用手动添加。能够经过新搭建基架的项目命令来完成。
先完成上面的1,2两个步骤,而后在Controllers文件夹上右键==》添加==》新搭建基架的项目
在模型类中选择第二步添加的模型student,数据上下文类中,点击后面的+号,将名称改成sqlserver,其余的默认就行,最后点击添加。系统会自动的建立数据上下文,而且还帮你注册了,除此以外,还添加了students控制器和相应的视图,对于控制器和视图能够保留,也能够删掉。剩下的须要修改一下配置文件中数据库的链接字符串,而后接着第五步继续就能够了。
2、当模型修改或者添加新的模型后
一、修改模型student,添加一个学号字段code;添加模型course,每一个学生能够报多个课程,每一个课程能够有多个学生报名,所以student和course是多对多的关系,须要一个中间表来关联,因此添加模型Enrollment。修改后的模型以下:
public class Student { [DatabaseGenerated(DatabaseGeneratedOption.None)] public Guid ID { set; get; } [Required] [MaxLength(30)] public string Name { set; get; } [Required] [MaxLength(30)] public string Code { set; get; } public int Age { set; get; } public byte Sex { set; get; } public string Remark { set; get; } [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreateDate { set; get; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime LastUpdate { set; get; } public ICollection<Enrollment> Enrollments { get; set; } } public class Enrollment {
public int EnrollmentID { get; set; } public int CourseID { get; set; } public Guid StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } } public enum Grade { A, B, C, D, F } public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }
修改数据上下文
public class SqlServerContext : DbContext { public SqlServerContext(DbContextOptions<SqlServerContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>().ToTable("Student"); modelBuilder.Entity<Course>().ToTable("Course"); modelBuilder.Entity<Enrollment>().ToTable("Enrollment"); } public DbSet<Student> Students { get; set; } public DbSet<Enrollment> Enrollments { get; set; } public DbSet<Course> Courses { get; set; } }
二、迁移
执行这个命令后,在Migrations文件夹中添加了20190329030918_AddTable.cs文件,里面的内容就是关于模型的修改的一些代码
继续执行命令dotnet ef database update
完过后,数据库中表已经正常添加了
经过上面的方式,在student表中添加了列code,新建的表Enrollment中有主键和外键。固然也能够不用设置外键,直接将表Enrollment的CourseID和StudentID设置为复合主键。这样的话,模型student中就不须要导航属性StudentID(Course,Enrollment中也是如此)。同时数据上下文中须要指定Enrollment表的复合主键:
modelBuilder.Entity<Enrollment>().ToTable("Enrollment").HasKey(c=>new { c.StudentID,c.CourseID});
这样一来,Enrollment中的EnrollmentID也要去掉。设置复合主键只能是在数据上下文中设置。
3、为数据库添加初始数据
在数据库中,有些表是有初始数据的,能够经过sql语句导入,在这里经过程序来实现吧
打开Program.cs文件,修改后:
public class Program { public static void Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; try { var context = services.GetRequiredService<SqlServerContext>(); Initialize(context); } catch (Exception ex) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occurred while seeding the database."); } } host.Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); private static void Initialize(SqlServerContext context) { if (!context.Courses.Any()) { var courses = new Course[] { new Course{CourseID=1050,Title="数学",Credits=3}, new Course{CourseID=4022,Title="语文",Credits=3}, new Course{CourseID=4041,Title="英语",Credits=3}, new Course{CourseID=1045,Title="化学",Credits=4}, new Course{CourseID=3141,Title="生物",Credits=4}, new Course{CourseID=2021,Title="物理",Credits=3}, new Course{CourseID=2042,Title="体育",Credits=4} }; foreach (Course c in courses) { context.Courses.Add(c); } context.SaveChanges(); } } }
运行程序,数据就会添加到数据库了。
4、数据库表里面有数据的状况下修改表结构
这里的修改确定是合理的修改,不能说你将字符串的列改为了数字的列。这里试验一下添加新的列,不能为空的
一、在course模型中,添加一个非空的字段
二、迁移
执行完迁移的第一个命令后,打开系统添加的文件,找到Up方法
能够看到up方法里面只有影响修改的部分,要设置一个非空列的初始值,就须要在这里改代码了,改好了以后执行迁移的第二个命令。查询数据库,表结构已经更改,并且里面的数据也没有丢失。
关于EF CORE的应用的基本介绍就到这里,更深刻的学习仍是参考微软官方文档吧