【EF Core 】实体映射table-- 实体特性(Data Annonation 标注)&Fluent Api
内容来源:组件模型之数据标注
目录
采用System.ComponentModel.DataAnnotations注解Model的字段
实体特性(Data Annonation 数据标注): 将实体映射到数据表格。数据标注除了用于数据映射还可以用与数据验证。
Data Annonation & FluentApi
Data Annonation Attributes
数据映射功能
Table
Column
Key
NotMapped
ForeignKey
Index
InverseProperty todo
NotMapped
数据验证功能
Required
MaxLength MinLength
StringLength
TimeStamp
DatabaseGenerated
ConcurrencyCheck
Fluent Api
实体映射
属性映射
————————————————
案例
[Table("StudentInfo")] public class Student { public Student() { } [Key] public int SID { get; set; } [Column("Name", TypeName="text")] //对应数据库的中列 [MaxLength(20)] public string StudentName { get; set; } [NotMapped] public int? Age { get; set; } public int StdId { get; set; } [ForeignKey("StdId")] public virtual Standard Standard { get; set; } }
实体特性(Data Annonation 标注)详解
Table
Table(string name,Properties:[Schema=string])
name:db table name
Schema:要创建的表的架构
如果没有指定些特性,将创建默认的表Students or Studentes
格式:(TableName+‘s’(or ‘es’)
如果指定则按指定的名创建
[Table("StudentInfo")]//将Student实体映射到数据库中的StudentInfo表格 public class Student { }
using System.ComponentModel.DataAnnotations.Schema; [Table("StudentMaster", Schema="Admin")] public class Student { public int StudentID { get; set; } public string StudentName { get; set; } }
Column
[Column(string name,Properties:[Order=int],[TypeName=string])
- 列名: Name of a column in a db table.
- 列索引: Order of a column, starting with zero index. (可选)
- TypeName: Data type of a column. (可选)
索引从0开始,并且不能有重复索引
public class Student { public int StudentID { get; set; } [Column("Name")] public string StudentName { get; set; } [Column("DoB", TypeName="DateTime2")] public DateTime DateOfBirth { get; set; } public byte[] Photo { get; set; } public decimal Height { get; set; } public float Weight { get; set; } }
列的排序
using System.ComponentModel.DataAnnotations.Schema; public class Student { [Column(Order = 0)] public int StudentID { get; set; } [Column("Name", Order = 1)] public string StudentName { get; set; } [Column("DoB", Order = 5)] public DateTime DateOfBirth { get; set; } [Column(Order = 3)] public byte[] Photo { get; set; } [Column(Order = 2)] public decimal Height { get; set; } [Column(Order = 4)] public float Weight { get; set; } }
Key 主键
下面的为组合主键
public class Student { [Key] [Column(Order=1)] public int StudentId{get;set;} [Key] [Column(Order=2)] public string StudentName }
ForeignKey 外键
Index 索引
[Index("IndexName,IsClustered=true,IsUnique=true)]
public int OrderNumber{get;set;}
Required
必输选项Not Null Column Required
public class Student { public int StudentID { get; set; } [Required]//对应的数据库列不能为空null public string StudentName { get; set; } }
MaxLength MinLength
C#中对应类型可以string 或 byte[]
using System.ComponentModel.DataAnnotations; public class Student { public int StudentID { get; set; } [MaxLength(50)] public string StudentName { get; set; } }
StringLength
可变长度 nvarchar(50)
[StringLength(50)]
public string Name{get;set;}
public string Name{get;set;}
sqlserver中,将转为数据库中的nvarchar(max)
mysql转为longtext
加上
[MaxLength]转为varchar(50)
[MinLength(50)]转为longtext
[StringLength(50)]也是转为varchar(50) ,
using System.ComponentModel.DataAnnotations; public class Student { public int StudentID { get; set; } [StringLength(50)] public string StudentName { get; set; } }
NotMapped 特性
不映射实体的属性到数据库表格中的列。
[NotMpaaed] public string StudentName { get; set; }
// 此列不会在数据库中创建相关的列。 ///如果属性只有get或set,也不会创建相关列。如下: public int Age { get { return _age; } } public double Height { set { _height = value; } }
DatabaseGenerated
- 1.DatabaseGeneratedOption.None
自己输入值,不用数据库生成的
public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseId { get; set; } public string CourseName { get; set; } } /* ef core api 中配置 modelBuilder.Entity<Course>() .Property(p => p.CourseId) .ValueGeneratedNever(); */
2.DatabaseGeneratedOption.Identity
根据具体的数据库来生成,插入后值不可更新。
有identity rowversion guid 等
public class Course { public int CourseId { get; set; } public string CourseName { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int RecordNum { get; set; } } /* ef core api modelBuilder.Entity<Course>().Property(p=>p.CourseId).ValueGeneratedOnAdd(); */
3.DatabaseGeneratedOption.Computed
在插入或更新的时候来设置值,需要我们自己计算的值
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } public DateTime? DateOfBirth { get; set; } public decimal Height { get; set; } public float Weight { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime CreatedDate { get; set; } } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entry<Student>().Property(s=>s.CreateDate) .HasDefaultValueSql("GETDATE()"); //这个是调用sqlserver的函数来设置它的值 没有试 }
ConcurrencyCheck
concurrencycheck与timestamp区别
concurrencycheck可用于多个属性的任意数据类型的检测
timestamp只可用于一个byte[]类型属性的检测,一个实体中只可有一个此类型
public class Student { [Key] public int Sid { get; set; } [ConcurrencyCheck] public string Sname { get; set; } //[Timestamp] mysql中无效 public byte[] RowVersion; public virtual StudentAddress Address { get; set; } }
TimeStamp
一个实体类中只可有一个类型为TimeStamp,用于并发检测
[TimeStamp],SQLServer中是这样,但是没有装,我也没试。在MySql中,此法无效。需要加入ConCurrencyCheck
public byte[] TimeStamp{get;set;}
参考
在mysql中如果将属性设置为[Timestamp]将报错。
在这里插入图片描述
public class Student { [Key] public int Sid { get; set; } [ConcurrencyCheck] public string Sname { get; set; } //[Timestamp] mysql中无效 public byte[] RowVersion; public virtual StudentAddress Address { get; set; } }
Fluent Api
实体映射
public class SchoolDBContext: DbContext { public SchoolDBContext(): base("SchoolDBConnectionString") { } public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } public DbSet<StudentAddress> StudentAddress { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure domain classes using modelBuilder here.. //config default schema modelBuilder.HasDefaultSchema("Admin"); //map entity to table modelBuilder.Entity<Student>().ToTable("StudentInfo"); modelBuilder.Entit<Student>().ToTable("StandardInfo","dbo"); //map to multiple tables modelBuilder.Entity<Student>().Map(m=> { m.Properties(p=>new {p.StudentId,p.StudentName}); m.ToTable("StudentInfo"); }).Map(m=> { m.Properties(p=>new {p.StudentId,p.Height,p.Weight,p.Photo}); m.ToTable("StudentInfoDetail"); }); modelBuilder.Entity<Standard>().ToTable("StandardInfo"); } }
将一个表分割为2个表
也可使用委托或表达式
using System.Data.Entity.ModelConfiguration.Configuration; namespace CodeFirst_FluentAPI_Tutorials { public class SchoolContext: DbContext { public SchoolDBContext(): base() { } public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>().Map(delegate(EntityMappingConfiguration<Student> studentConfig) { studentConfig.Properties(p => new { p.StudentId, p.StudentName }); studentConfig.ToTable("StudentInfo"); }); Action<EntityMappingConfiguration<Student>> studentMapping = m => { m.Properties(p => new { p.StudentId, p.Height, p.Weight, p.Photo, p.DateOfBirth }); m.ToTable("StudentInfoDetail"); }; modelBuilder.Entity<Student>().Map(studentMapping); modelBuilder.Entity<Standard>().ToTable("StandardInfo"); } } }
属性映射
ublic class SchoolContext: DbContext { public SchoolDBContext(): base() { } public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Configure primary key modelBuilder.Entity<Student>().HasKey<int>(s => s.StudentKey); modelBuilder.Entity<Standard>().HasKey<int>(s => s.StandardKey); //Configure composite primary key modelBuilder.Entity<Student>().HasKey<int>(s => new { s.StudentKey, s.StudentName }); //config column modelBuilder.Entity<Student>() .Property(p=>p.DataofBirth) .HasColumn("DoB") .HasColumnOrder(3) .HasColumnType("datetime2") .IsOption() //null .IsRequired()//not null .HasMaxLength(50) .HasMaxLength(50).IsFixedLength()//change type from nvarchar to nchar .HasPrecision(2,2) //set size decimal(2,2) .IsCurrencyToken()//concurrency check .IsRowVersion()//timestamp type byte[] make it as concurrency column ; } }
级联删除
EF配置的外键关系除了配置为Optional(可选的,也就是可空),其他默认都是级联删除的,意思就是删除主表的某个数据,相关联的从表数据都自动删除:
C# 数据类型和对应的SQL Sever数据类型.
C# Data Type | Mapping to SQL Server Data Type |
---|---|
int | int |
string | nvarchar(Max) |
decimal | decimal(18,2) |
float | real |
byte[] | varbinary(Max) |
datetime | datetime |
bool | bit |
byte | tinyint |
short | smallint |
long | bigint |
double | float |
char | No mapping |
sbyte | No mapping (throws exception) |
object | No mapping |