asp.net

EF Core的实体类配置

2023-03-09

本文主要讨论实体类和数据表是如何映射的,以及实体类中的属性是如何与数据表中的列映射的。

约定大于配置

EF Core会默认按照约定根据实体类和DbContext上下文类的定义来实现和数据库表的映射配置,除非用户指定了配置规则,简而言之:默认

主要规则如下:

1)数据库名采用上下文类中对应的DbSet的属性名

2)数据库表列的名字采用实体类属性的名字,列的数据类型采用和实体类属性类型兼容的类型。string->nvarchar;long->bigint

3)数据库表列的可空性取决于对应实体类属性的可空性

4)名字为Id的属性为主键,如果主键为short、int、long类型,则自动增长

Data Annotation

使用.net提供的Attribute对实体类、属性进行标注,来实现实体类的配置。

[Table("T_Books")] //将数据库表名设置为T_Books

public class Book

{

    public long Id { get; set; }//主键

//将Title属性最大长度设置为50,且不能为空

    [MaxLength(50)] 

    [Required]

    public string Title { get; set; }//标题

    public DateTime PubTime { get; set; }//发布日期

    public double Price { get; set; }//单价

    [MaxLength(20)]

    [Required]

    public string AuthorName { get; set; }//作者名字

}


Fluent API

编写实现了IEntityTypeConfiguration接口的实体配置类。


1)视图与实体类映射

modelBuilder.Entity<Blog>().ToView("blogsView");将数据库视图blogsView与Blog映射


2)排除属性映射

默认情况,一个实体类的所有属性都会映射到数据库表中,使用Ignore忽略某些属性

modelBuilder.Entity<Blog>().Ignore(b=>b.name);//将name属性排除


3)数据库表列名称改变

默认和属性名相同,可以使用HasColumnName进行改变

modelBuilder.Entity<Blog>().Property(b=>b.BlogId).HasColumnName(blog_id);将BlogID改为blog_id


4)列的数据类型

Title为string类型,默认生成nvarchar类型,通过下面语句改为varchar类型

builder.Property(e=>e.Title).HasColumnType("varchar(200)");


5)主键

默认把Id或者实体类型+Id属性作为主键。下面可以把Number设置为主键。

modelBuilder.entity(Student)().HasKey(c=>c.Number);


6)索引

将Blog实体类的Url属性定义为索引

modelBuilder.Entity<Blog>().HasIndex(b=>b.Url);


复合索引,将Person实体类的FirstName和LastName定义为复合索引


modelBuilder.Entity<Person>().HasIndex(p=>new {p.FirstName,p.LastName})


默认情况下,定义的索引不是唯一索引,可以使用IsUnique把索引配置为唯一索引,还可以使用IsClustered把索引设置为聚集索引。


**注意:**以上凡是modelBuilder开头的都是在上下文类进行设置,而builder类开头则是在实体配置类中进行设置。某些设置可以在两个类中都可以。例如:


//两者意义相同

builder.HasIndex(b => b.Url);

modelBuilder.Entity<Blog>().HasIndex(b=>b.Url);


主键类型

通常使用自增long类型,新插入数据后会自动增长,但是自增系列的值一般由数据库生成,只能把数据保存后才能获得主键的值。所以通常使用一下两种方式作为主键。


1)Guid类型

由于guid的值是不连续的,所以不能将guid的主键设置为聚集索引。


class Author

{

public Guid Id {set;get;}

public string name {set; get;}

}


Author a = new Author{Name = "张三"}

ctx.Authors.add(a);

await ctx.SaveChangesAsync;


2)自增+Guid类型

自动主键和Guid结合的方式,guid列只作为逻辑主键。