EntityFramwork Core
EntityFramework 是ORM。
一种让你可以使用 面向对象 的范式对数据库进行查询和操作。
通常情况,ORM可以把数据库中的表和Model对象一一映射起来。
EF支持两种模式:
1.先写C#(model),然后生成数据库
2.先建表,然后生成C#的model
建议使用CodeFirst
一、创建Entity
Entity就是普通的C#类,类似于Dto。Dto是与外界打交道的Model,entity则不一样有一些Dto的计算属性我们并不想保存在数据库中,所以entity中并没有这些属性,而数据从entity传递到Dto后某些属性也会和数据库里面的形式不一样。
二、DbContext
EFCore使用一个DbContext和数据库打交道
他代表着和数据库之间的一个Session,可以用来查询和保存我们的entities。
DbContext需要一个Provider,便于访问数据库
所以我们建立一个DbContext,建立MyContext并集成DbContext。
namespace CoreBackend.Api.Entities
{
public class MyContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
}
这里我们为Product创建了一个类型为
Dbset<T>
的属性,它可以用来查询和保存实例。(针对Dbset的LinQ查询语句会解释成针对数据库的查询语句)。
因为我们需要使用这个MyContext,所以就需要先在Container中注册它,然后就可以在依赖注入中使用了。
//默认的生命周期是Scoped
services.AddDbContext<MyContext>();
为DbContext提供连接字符串:
1.MyContext中的 override OnConfiguring
namespace CoreBackend.Api.Entities
{
public class MyContext : DbContext
{
//针对于Product的映射
public DbSet<Product> Products { get; set; }
//配置数据库连接(固定步骤)
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("xxxx connection string");
base.OnConfiguring(optionsBuilder);
}
}
}
2.在constructure内使用
namespace CoreBackend.Api.Entities
{
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options)
:base(options)
{
}
public DbSet<Product> Products { get; set; }
}
}
它可以在我们注册MyContext的时候就提供options
StartUp类写
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
#if DEBUG
services.AddTransient<IMailService, LocalMailService>();
#else
services.AddTransient<IMailService, CloudMailService>();
#endif
//定义连接字符串
var connectionString = @"Server=(localdb)\MSSQLLocalDB;Database=ProductDB;Trusted_Connection=True";
//注册服务时就使用
services.AddDbContext<MyContext>(o => o.UseSqlServer(connectionString));
}
此时我们建立一个controller来调用生成这个数据库和表。
Database.EnsureCreated()确实可以保证创建数据库,但是随着代码不断被编写,我们的Model不断再改变,数据库应该也随之改变,而EnsureCreated()就不够了,这就需要迁移(Migration)。
Fluet Api
针对Product这个entity,我们需要把他映射成一个数据库的表,针对每个属性,我们需要做一些设定,例如最大长度,是否必填。
针对Product,我们可以在MyContext里面写override OnModelCreating这个方法。
1.使用一个IEntityTypeConfiguration<T>
,建立一个ProductConfiguration的类
public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Name).IsRequired().HasMaxLength(50);
builder.Property(x => x.Price).HasColumnType("decimal(8,2)");
}
}
2.配置MyContext里面的OnModelCreating方法
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new ProductConfiguration());
}
迁移Migration
随着代码的改变,数据库也会跟着变,所有的EnsureCreated()不满足要求,migration允许我们升级我们的数据库版本
在Package Manager Console,使用Add-Migration xxxx指令来做数据库迁移。
保证migration都邮箱的应用于数据库 Update-Database
种子数据Seed Data