ORM : Object Relational Mapping。让开发者用对象操作的形式操作关系数据库。
从面向数据库集中到面向对象。
Nuget
Microsoft.EntityFrameworkCore
//针对于sqlserver
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
//在vs中需要装
Microsoft.EntityFrameworkCore.Tools
EFCore也是约定大于配置
基本操作步骤
-
建实体类;
class Books { public long Id { get; set; } public string Title { get; set; }//标题 public DateTime PubTime { get; set; }//发布日期 public double Price { get; set; }//单价 }
-
创建配置类;
class BookConfig : IEntityTypeConfiguration<Books> { public void Configure(EntityTypeBuilder<Books> builder) { builder.ToTable("T_Books"); } }
-
建DbContext;
class MyDbConnect : DbContext { public DbSet<Books> Books { get; set; } public MyDbConnect(DbContextOptions options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); optionsBuilder.UseSqlServer("Server =. ;Database=demo1; Trusted_Connection=True;MultipleActiveResultSets = true"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //从当前程序集中寻找实现IEntityTypeConfiguration<>接口的类 modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); } }
-
生成数据库;
//生成一次迁移 Add-Migration <名称> //执行对操作数据库 Update-Database
-
编写调用EF Core的业务代码;
EFCore数据的增删改查
插入数据
using (MyDbConnect connect=new MyDbConnect())
{
Books book = new Books();
book.AuthorName = "李名";
connect.Books.Add(book);
connect.SaveChanges();
}
结合Linq查询数据
private static async Task Main(string[] args)
{
using (MyDbConnect connect=new MyDbConnect())
{
IQueryable<Books> books = connect.Books.Where(e => e.Title == "围城");
foreach (var item in books)
{
await Console.Out.WriteLineAsync(item.AuthorName);
}
await connect.SaveChangesAsync();
Console.ReadKey();
}
}
删除和修改有点特殊
修改
要对数据进行修改,首先需要把要修改的数据查询出来,然后
再对查询出来的对象进行修改,然后再执行SaveChangesAsync()
保存修改。
var b=ctx.Books.Single(b=>b.Title == "数学之美”);
b.AuthorName = "Jun Wu";
await ctx.SaveChangesAsync();
删除
删除也是先把要修改的数据查询出来,然后再调用DbSet或者
DbContext的Remove方法把对象删除,然后再执行
SaveChangesAsync()保存修改。
var b=ctx.Books.Single(b=>b.Title == "数学之美”);
ctx.Remove(b);//也可以写成ctx.Books.Remove(b);
await ctx.SaveChangesAsync();
批量删除和修改EF7已经适配
约定配置
主要规则:
-
表名采用DbContext中的对应的DbSet的属性名。
-
数据表列的名字采用实体类属性的名字,列的数据类型
采用和实体类属性类型最兼容的类型。
-
数据表列的可空性取决于对应实体类属性的可空性。
-
名字为Id的属性为主键,如果主键为short,int或者long类型,则默认采用自增字段,如果主键为Guid类型,则默认采用默认的Guid生成机制生成主键值。
两种配置方式
Data Annotation
把配置以特性(Annotation)的形式标注在实体类中。
模型注解
[Table("T_Books")]
public class Book
{
}
优点:简单;缺点:耦合。
Fluent API
builder.ToTable("T_Books");
把配置写到单独的配置类中。
缺点:复杂;优点:解耦
-
视图与实体类映射:
modelBuilder.Entity
().ToView("blogsView"); -
排除属性映射:忽略掉
modelBuilder.Entity
().Ignore(b=> b. Name2); -
配置列名:
modelBuilder.Entity<Blog().Property(b=>b.BlogId).HasColumnName("blog_id");
-
配置列数据类型:
builder.Property(e => e.Title) .HasColumnType("varchar(200)")
-
配置主键
默认把名字为Id或者“实体类型+Id“的属性作为主键,可以用HasKey()来配置其他属性作为主键。modelBuilder.Entity
().HasKey(c=>c.Number); -
生成列的值
modelBuilder.Entity().Property(b =>
b.Number). ValueGeneratedOnAdd(); -
可以用HasDefaultValue()为属性设定默认值
modelBuilder.Entity().Property(b =>
b.Age).HasDefaultValue(6); -
索引
modelBuilder.Entity().HasIndex(b=> b.Url); -
复合索引
modelBuilder.Entity().HasIndex(p => new { p.FirstName,
p.LastName }); -
唯一索引:
IsUnique();
builder. HasIndex(b=>b.Title). IsUnique() ; builder. HasIndex(b=>new { b.Name2, b.AuthorName }) ;
聚集索引:IsClustered()
-
用EF Core太多高级特性的时候谨慎,尽量不要和业务逻辑混合在一起,以免“不能自拔”。比如Ignore、Shadow、Table Splitting等 ……
在实现IEntityTypeConfiguration<>接口的类中,可以定义些什么
- 设置表名:使用
.ToTable("table_name")
方法可以设置实体对应的数据库表名。 - 设置模式:使用
.ToTable("table_name", "schema_name")
方法可以设置模式(schema)。 - 配置主键:使用
.HasKey(e => e.Id)
方法可以设置实体的主键。 - 配置索引:使用
.HasIndex(e => e.Property)
方法可以为某个属性创建索引。 - 配置唯一约束:使用
.HasAlternateKey(e => e.Property)
方法可以为某个属性创建唯一约束。 - 配置关系:使用
.HasOne()
,.WithMany()
,.HasForeignKey()
等方法可以配置实体之间的关系,如一对多、多对多等。 - 配置属性:使用
.Property(e => e.Property)
可以对属性进行配置,如设置最大长度、精度、是否可空等。 - 忽略属性:使用
.Ignore()
方法可以忽略实体中的某个属性,使其不映射到数据库表中。 - 配置注释:使用
.HasComment("comment")
方法可以为表或列添加注释。 - 配置序列生成:使用
.HasDefaultValueSql()
,.ValueGeneratedOnAdd()
,.ValueGeneratedOnAddOrUpdate()
等方法可以配置属性的默认值或生成策略。 - 配置转换:使用
.HasConversion()
方法可以配置属性的数据库类型转换。 - 配置存储:使用
.HasColumnName("column_name")
可以设置属性映射到数据库表中的列名。 - 配置读取/写入:使用
.ForSqlServerHasColumnType()
,.ForSqlServerToTable()
等方法可以为特定数据库提供者配置特定的属性。 - 配置继承:如果实体类型之间存在继承关系,可以使用
.HasDiscriminator()
,.HasBaseType()
等方法来配置。 - 配置影子属性:使用
.HasShadowProperty()
可以为实体添加一个影子属性,它不会映射到数据库表中,但可以在应用中使用。