DataAnnotations 模型配置
当我们在构建模型的时候,除使用约定来定义实体类以外,还可以使用 数据注释(特性) 和 Fluent API(重写 OnModelCreating 方法) 的方式来配置模型
注意:Fluent API > 注释 > 约定
- 包括和排除类型或者属性
- 按照约定,有三种方式可以发现类型;DbSet中的类型,在 OnModelCreating 中的类型,在已发现类型中发现的其它任何类型;
- 使用 注释 方法排除
[NotMapped] public class BlogUpdate { public int BlogId { get; set; } public DateTime updateTime { get; set; } }
- 使用 Fluent API 排除
builder.Ignore<BlogDetail>();
builder.Entity<BlogDetail>().Ignore(b => b.LoadedFromDatabase);
- 主键
- 按照约定,名为 Id 或者 <type name>Id 的属性会被配置成主键
- 注释 方式: [Key]
- Fluent API 方式:
builder.Entity<Car>().HasKey(c => c.LicensePlate);
还可以使用 Fluent API 将多个属性设置成主键(复合键)
builder.Entity<Car>().HasKey(c => new { c.State, c.LicensePlate });
- 必需和可选
- 按照约定,不能设置 null 的属性将自动认为属性必需,如 int/decimal/bool 等
- 特性名称: [Required]
- Fluent API:
builder.Entity<Blog>().Property(b => b.Url).IsRequired();
- 最大长度
- 按照约定,最大长度仅适用于数组数据类型的属性,如 string / byte[]
- 注释方式: [MaxLength(10)]
- Fluent API 方式:
builder.Entity<Blog>().Property(b => b.Url).HasMaxLength(500);
- 并发标记
- 关系
- 索引
- 只能使用 Fluent API 来创建索引
- 默认情况下,索引是非唯一的;可以指定索引唯一;还可以指定多个列为索引
builder.Entity<Blog>().HasIndex(b => b.Url); builder.Entity<Blog>().HasIndex(b => b.Url).IsUnique(); builder.Entity<Person>().HasIndex(p => new { p.FirstName, p.LastName });
- 值的转换
- 初始数据(Data Seeding)
- 模型初始数据
builder.Entity<Blog>().HasData( new Blog { BlogId = 1, Url ="http://sample.com" });
- 模型初始数据
- 表特性
- 按照约定,默认将类名称设置为数据库表名称的标识,有必要下可以特别指定
- 注释方式:[Table("name"), Schema = "schema"]
- Fluent API 方式:
builder.Entity<Blog>().ToTable("blogs", schema: "blogging");
- 列特性
- 按照约定,每个属性将会设置为映射到与属性具有相同名称的列
- 当需要设置精确的数据类型,可以设置 TypeName 属性
- 注释方式:[
-
builder.Entity<Blog>().Property(b => b.BlogId).HasColumnName("blog_id");
builder.Entity<Blog>(eb =>
{
eb.Property(b => b.Url).HasColumnType("varchar(200)");
eb.Property(b => b.Rating).HasColumnType("decimal(5, 2)");
});
- 默认值
- 按照约定,如果插入新行,未指定值的列将被插入默认值
- Fluent API 方式:
builder.Entity<Blog>().Property(b => b.Rating).HasDefaultValue(3); builder.Entity<Blog>().Property(b => b.Created).HasDefaultValueSql("getdate()");