一、搭建项目
在我们日常项目中,一般都会是多层架构,领域层(实体)一般是不会和应用层(业务:如api,mvc)放在一块的,只有做练习的时候才会这么干,那我就直接分享最实用的了,按照最基本的做项目的分层来。
建一个ASP.NET Core的API项目和一个.NET Core的类库(注意是Core版本的,不是framework)
二、安装依赖包
选中Model类库,打开nuget程序包管理器,搜索Microsoft.EntityFrameworkCore.SqlServer安装,安装最新版本的时候,请注意你的项目是否是.net6或.net5,我这边用的还是3.1,所以下的包是5.0.12版本。
再选中api项目,下载Microsoft.EntityFrameworkCore.Tools包,也是5.0.12版本的,该包主要用于执行迁移命令:add-migration;update-database,以及数据库反向生成实体代码等命令
三、新建实体、数据库上下文
在model类库的根目录下面新建两个类,BaseModel和DbContext(数据库上下文),BaseModel是通用的一些字段,比如id,createtime,isdelete这些几乎每个实体类都会用得上的可以抽离出来
id使用到了virtual,是因为有些表我们可能需要id为int类型或long、string,使用virtual可以让子类重写该字段
public class BaseModel
{
public virtual Guid Id { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 删除状态
/// </summary>
public bool IsDelete { get; set; }
}
数据库上下文类需要继承DbContext并在构造函数中调用父类的构造函数,该类来源于using Microsoft.EntityFrameworkCore命名空间,是我们安装的包里面的。
public class CSDNDbContext:DbContext
{
public CSDNDbContext(DbContextOptions<CSDNDbContext> options):base(options)
{
}
}
然后我们新建文件夹Entity,在Entity文件夹下面建一个EntityEnum文件夹用于放一些枚举类型,我们先在Entity文件夹中建一个student实体类。
using System;
using System.Collections.Generic;
using System.Text;
using CSDN.Model.Entity.EntityEnum;
namespace CSDN.Model.Entity
{
public class Student:BaseModel
{
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 出生日期
/// </summary>
public DateTime Birthday { get; set; }
/// <summary>
/// 性别
/// </summary>
public SexType Sex { get; set; }
/// <summary>
/// 邮箱
/// </summary>
public string Email { get; set; }
}
}
SexType建在EntityEnum文件夹中
namespace CSDN.Model.Entity.EntityEnum
{
public enum SexType
{
/// <summary>
/// 男
/// </summary>
Male,
/// <summary>
/// 女
/// </summary>
Female
}
}
实体类建完以后我们在数据库上下文中添加该实体类
public class CSDNDbContext:DbContext
{
public CSDNDbContext(DbContextOptions<CSDNDbContext> options):base(options)
{
}
public DbSet<Student> Students { get; set; }
}
四、执行迁移命令,生成数据库
在api项目中的app setting.json文件夹中添加数据库连接字符串
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"CSDNDB": "server=.;database=csdnDb;user id=sa;password=123456;"
}
}
在startup类中的ConfigureServices方法中注册数据库上下文,两种方法,一个是services.AddDbContext<>(),第二个是AddDbContextPool。我们需要通过读取app setting.json中的连接字符串来生成数据库,在Startup类中,ASP.NET Core已经为我们提供了读取连接字符串的方法,Configuration.GetConnectionString();参数需要传入我们刚刚添加的key:"CSDNDB",两者需要一致。
AddDbContext()和AddDbContextPool0方法之间的区别:
在编写代码的时候,它会提示选择services.AddbContext还是services. AddDbContextPool0
我们在下方的代码中选择了services.AddDbContextPool。我们可以使用AddDbContext0或AddDbContextPool0方法向ASP.NET Core依赖注入容器中注册程序中的DbContext类。AddDbContext()和AddDbContextPool0方法的区别在于,AddDbContextPool0方法提供了数据库连接池(DbContextPool)。
如果数据库连接池是可用的, 则会提供数据库连接池中的实例,而不是创建新的实例。数据库连接池在概念上类似于以前ADO.NET中连接池的工作方式。从性能角度来看选择AddDbContextPool的原因是, AddDbContextPool方法的性能优于AddDbContext方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//或者是services.AddDbContext<>(...)
services.AddDbContextPool<CSDNDbContext>(option => {
option.UseSqlServer(Configuration.GetConnectionString("CSDNDB"));
});
}
然后我们将启动程序设置为api项目,打开程序包管理器控制台,选中model层,输入add-migration initdatabase生成迁移文件。
它会在你的model层的根目录下生成migration文件夹,并添加了一个迁移类
然后我们再执行update-database命令生成数据库,然后就生成了数据库和表,可以看到我们student实体类中的每个字段都生成了。
五、ef小知识
1,add-migration “迁移名称” 迁移名称我们通常以你本次迁移的目的来命名,比如你新增了一个student实体“add_student_table”,修改了一个字段“update_xxx_Field”等,尽量不随便命名。
2,生成迁移文件后,在执行update-database之前可以通过执行remove-migration删除刚刚生成的迁移文件,一次只能删除一个,并且只能删除你还未执行update-dabase的迁移文件
3,执行udpate-database,在生成数据库时,它并不是每次都将所有的表去重新生成,在migration文件夹中有个快照文件的类,生成数据库时每次会对比快照文件,从而知道每次需要修改什么或添加什么。如果你拿到别人的项目第一次执行update-database,ef会将所有的迁移文件依次执行。
4.update-database可以指定迁移文件执行:假如某次生成数据库,发现生成后的数据库有问题想要回到上一个版本,我们可以通过指定迁移名称取生成数据库 update-databse init2
5.枚举类型在生成后会自动转化为int类型