约定配置
1、主要规则
-
表名采用
DbContext
中对应的DbSet
的属性名 -
数据表列的名字采用实体类属性的名字, 列的数据类型采用喝实体类属性类型最兼容的类型, 可以自定义设置
-
数据表列的可空性取决于对应实体类属性的可空性
-
名字为
Id
的属性为主键-
如果主键为
short
,int
或者long
则默认采用自增 -
如果主键为
Guid
, 则默认采用Guid
生成机制生成主键值
-
2、两种配置方法
(0)两种方法结合
-
两种方法大部分功能重叠, 可以混用, 不推荐
(1)Data Annotation
-
把配置以特性(
Annotation
)的形式标注在实体类中 -
简单但耦合
[Table("T_Books")]
public class Book
{
public long Id { get; set; }
[Required]
[MaxLength(50)]
public string Title { get; set; }
public DateTime PubTime { get; set; }
public double Price { get; set; }
[Required]
[MaxLength(50)]
public string AuthoName { get; set; }
}
(2)Fluent API
单独写个Configuration
, 常用
-
建议每个实体建一个单独的配置类, 再把配置写到单独的配置类中
-
复杂却解耦
// book表的实体类配置
public class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
//绑定表
builder.ToTable("T_Books");
//设置字段属性
builder.Property(b => b.Title).HasMaxLength(50).IsRequired();
builder.Property(b => b.AuthoName).HasMaxLength(20).IsRequired();
}
}
// 自定义数据库表配置
public class MyDbContext : DbContext
{
// 映射表
public DbSet<Book> Books { get; set; }
// 指定链接数据库
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);
//note 从当前程序集加载所有的表 => 类Configuraton, 所有实现IEntityTypeConfiguration<T>的类
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
Fluent API
1、API
(1)视图
-
视图与实体类映射
-
不建议用视图
modelBuilder.Entity<Blog>().ToVie("blogsView");
(2)排除属性映射
-
在
DbContext
中modelBuilder.Entity<T>.Ignore(e => e.Prop)
-
在表的
Config
中builder.Ignore(e => e.Prop)
public class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
//绑定表
builder.ToTable("T_Books");
//排除属性映射
builder.Ignore(b => b.Price);
}
}
(3)设置列名
public class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
//绑定表
builder.ToTable("T_Books");
//设置列名
builder.Property(b => b.PubTime).HasColumnName("pub_time");
}
}
modelBuilder.Entity<T>(e => e.Prop).HasColumnName("prop");
(4)设置列数据类型
public class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
//绑定表
builder.ToTable("T_Books");
//设置数据类型
builder.Property(b => b.Title).HasColumnType("varchar(200)");
}
}
modelBuilder.Entity<T>(e => e.Prop).HasColumnName("prop");
(5)配置主键
-
默认把名字为Id或者
实体名+Id
的属性作为主键, 可以用HasKey()
来配置 -
支持复合主键, 不建议使用
public class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
//绑定表
builder.ToTable("T_Books");
//设置主键
builder.HasKey(b => b.Id);
}
}
public class MyDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//...
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//设置主键
modelBuilder.Entity<Book>().HasKey(x => x.Id);
}
}
(6)生成列的值
-
比如像某种计算列的生成, 不建议使用
builder.Property(b => b.Price).ValueGeneratedOnAdd();
(7)为属性设置默认值
builder.Property(b => b.Title).HasDefaultValue("aaa");
modelBuilder.Entity<Book>().Property(b => b.Title).HasDefaultValue("aaa");
(8)索引
A.索引
builder.HasIndex(b => b.Title);
modelBuilder.Entity<Book>().HasIndex(b => b.Title);
B.复合索引
builder.HasIndex(b => new { b.Id, b.Title });
modelBuilder.Entity<Book>().HasIndex(b => new { b.Id, b.Title });
C.唯一索引
builder.HasIndex(b => b.Title).IsUnique();
modelBuilder.Entity<Book>().HasIndex(b => b.Title).IsUnique();
D.聚合索引
builder.HasIndex(b => b.Title).IsClustered();
modelBuilder.Entity<Book>().HasIndex(b => b.Title).IsClustered();
2、尽量不要使用链式调用
-
链式调用取决于前一个方法的返回值是否可以作为当前方法的调用者