ASP.NET CORE 使用 EF CORE访问数据库

时间:2023-03-08 22:59:26
ASP.NET CORE 使用 EF CORE访问数据库

asp.net core通过ef core来访问数据库,这里用的是代码优先,通过迁移来同步数据库与模型。

环境:vs2017,win10,asp.net core 2.1

一、从建立asp.net core web项目开始

1、通过vs2017建立一个asp.net core web应用程序

ASP.NET CORE 使用 EF CORE访问数据库

2、在models文件夹下面创建一个student类,这个类用作数据模型,表示的是数据库里面的student表

public class Student
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid ID { set; get; }
[Required]
[MaxLength()]
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; }
}

关于表里面的特性说明这里暂时不管,等创建了数据库后再来说明。

3、创建数据库上下文

在项目中建立一个Data文件夹,创建一个类SqlServerContext

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方法中指定表名。

4、注册数据库上下文

打开 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验证。

5、迁移

通过命令行接口 (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

ASP.NET CORE 使用 EF CORE访问数据库

命令执行成功的话,会在项目中添加一个文件夹Migrations

ASP.NET CORE 使用 EF CORE访问数据库

这里面的两个文件就是EF如何创建数据库的,一般来说不需要手动去修改这两个文件。

这时候,数据库里面还没有相应的数据库和表

在cmd中执行命令dotnet ef database update,成功执行后,就可以在数据库里面看到创建的数据库和表了

ASP.NET CORE 使用 EF CORE访问数据库

6、分析

现在来看看student表的列和模型student的关系

ASP.NET CORE 使用 EF CORE访问数据库

系统默认ID是主键,这是一种约定,当然也可以在模型student的ID属性上用 [Key]来修饰,这时候ID可以是其他的名称。具体有关模型创建的信息,请参考创建并配置模型

模型中,ID的类型是guid,在数据库里面就对应类型uniqueidentifier,[DatabaseGenerated(DatabaseGeneratedOption.None)]特性表示ID列不需要数据库自动添加值。

Name和Remark都是string类型,remark没有任何修饰,所以数据库中的类型就是nvarchar(max),且可以为空。

7、步骤优化

上面的的6个步骤中,第3,4两步可以不用手动添加。可以通过新搭建基架的项目命令来完成。

先完成上面的1,2两个步骤,然后在Controllers文件夹上右键==》添加==》新搭建基架的项目

ASP.NET CORE 使用 EF CORE访问数据库

ASP.NET CORE 使用 EF CORE访问数据库

在模型类中选择第二步添加的模型student,数据上下文类中,点击后面的+号,将名称改为sqlserver,其他的默认就行,最后点击添加。系统会自动的创建数据上下文,并且还帮你注册了,除此之外,还添加了students控制器和相应的视图,对于控制器和视图可以保留,也可以删掉。剩下的需要修改一下配置文件中数据库的连接字符串,然后接着第五步继续就可以了。

二、当模型修改或者添加新的模型后

1、修改模型student,添加一个学号字段code;添加模型course,每个学生可以报多个课程,每个课程可以有多个学生报名,因此student和course是多对多的关系,需要一个中间表来关联,所以添加模型Enrollment。修改后的模型如下:

   public class Student
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid ID { set; get; }
[Required]
[MaxLength()]
public string Name { set; get; }
[Required]
[MaxLength()]
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; } }

2、迁移

ASP.NET CORE 使用 EF CORE访问数据库

执行这个命令后,在Migrations文件夹中添加了20190329030918_AddTable.cs文件,里面的内容就是关于模型的修改的一些代码

继续执行命令dotnet ef database update

完事后,数据库中表已经正常添加了

ASP.NET CORE 使用 EF CORE访问数据库ASP.NET CORE 使用 EF CORE访问数据库ASP.NET CORE 使用 EF CORE访问数据库

通过上面的方式,在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也要去掉。设置复合主键只能是在数据上下文中设置。

三、为数据库添加初始数据

在数据库中,有些表是有初始数据的,可以通过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=,Title="数学",Credits=},
new Course{CourseID=,Title="语文",Credits=},
new Course{CourseID=,Title="英语",Credits=},
new Course{CourseID=,Title="化学",Credits=},
new Course{CourseID=,Title="生物",Credits=},
new Course{CourseID=,Title="物理",Credits=},
new Course{CourseID=,Title="体育",Credits=}
};
foreach (Course c in courses)
{
context.Courses.Add(c);
}
context.SaveChanges();
} } }

运行程序,数据就会添加到数据库了。

四、数据库表里面有数据的情况下修改表结构

这里的修改肯定是合理的修改,不能说你将字符串的列改成了数字的列。这里试验一下添加新的列,不能为空的

1、在course模型中,添加一个非空的字段

ASP.NET CORE 使用 EF CORE访问数据库

2、迁移

执行完迁移的第一个命令后,打开系统添加的文件,找到Up方法

ASP.NET CORE 使用 EF CORE访问数据库

可以看到up方法里面只有影响修改的部分,要设置一个非空列的初始值,就需要在这里改代码了,改好了之后执行迁移的第二个命令。查询数据库,表结构已经更改,而且里面的数据也没有丢失。

关于EF CORE的应用的基本介绍就到这里,更深入的学习还是参考微软官方文档