Code Frist 数据注解及Fluent API
表映射 [Table(string name, Properties:[Schema = string])
[Table("DataTest", Schema = "admin")] //注释:[Table(string name, Properties:[Schema = string]) public class DataAnnotationsAttribute { [Key] [Column(Order = 1)] public int Id { get; set; } }
列映射 [Column (string name, Properties:[Order = int],[TypeName = string])
[Table("DataTest", Schema = "admin")] //注释:[Table(string name, Properties:[Schema = string]) public class DataAnnotationsAttribute { [Key] [Column(Order = 1)] public int Id { get; set; } [Column(Order = 3, TypeName = "varchar(50)")] public string Name { get; set; } [Column("FullName", Order = 2, TypeName = "varchar(60)")] // [Column (string name, Properties:[Order = int],[TypeName = string]) public string FullName { get; set; } // [ForeignKey] 参考 UserRole [DefaultValue(3)] public int DefaultValue { get; set; } }
Fluent api
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<DataAnnotationsAttribute>(eb => { eb.Property(b => b.Name).HasColumnType("varchar(50)"); eb.Property(b => b.FullName).HasColumnType("varchar(60)"); }); }
主键 [key]
数据注解方式: [Key] [Column(Order = 1)] public int Id { get; set; } Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasKey(b => b.BlogId).HasName("PrimaryKey_BlogId"); }
Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Car>().HasKey(c => new { c.LicensePlate, c.State }); }
计算列(列计算或拼接):数据注解中无法实现,只能在Fluent API中实现
class MyContext : DbContext { public DbSet<Person> People { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Person>() .Property(p => p.DisplayName) .HasComputedColumnSql("[LastName] + ', ' + [FirstName]"); } } public class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string DisplayName { get; set; } }
序列:数据注解中无法实现,只能在Fluent API中实现
class MyContext : DbContext { public DbSet<Order> Orders { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasSequence<int>("OrderNumbers", schema: "shared") .StartsAt(1000) .IncrementsBy(5); modelBuilder.Entity<Order>() .Property(o => o.OrderNo) .HasDefaultValueSql("NEXT VALUE FOR shared.OrderNumbers"); } } public class Order { public int OrderId { get; set; } public int OrderNo { get; set; } public string Url { get; set; } }
默认值:数据注解中无法实现(跟EF 不一样,即使提供,但没有效果),只能在Fluent API中实现
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Rating) .HasDefaultValue(3); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public int Rating { get; set; } }
索引:数据注解中无法实现(跟EF 不一样,即使提供,但没有效果),只能在Fluent API中实现
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 唯一索引 modelBuilder.Entity<Blog>().HasIndex(b => b.Url).IsUnique(); // 非唯一 modelBuilder.Entity<Blog>().HasIndex(b => new { b.RegistrationNumber1, b.RegistrationNumber2 }); }
外键约束 一对多:
// 实体 public class Student { public int Id { get; set; } public string Name { get; set; } public int CurrentGradeId { get; set; } public Grade Grade { get; set; } } public class Grade { public int GradeId { get; set; } public string GradeName { get; set; } public string Section { get; set; } public ICollection<Student> Students { get; set; } } // Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasOne<Grade>(s => s.Grade) .WithMany(g => g.Students) .HasForeignKey(s => s.CurrentGradeId); } public DbSet<Grade> Grades { get; set; } public DbSet<Student> Students { get; set; }
一对一:
// 实体 public class Student { public int Id { get; set; } public string Name { get; set; } public StudentAddress Address { get; set; } } public class StudentAddress { public int StudentAddressId { get; set; } public string Address { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public int AddressOfStudentId { get; set; } public Student Student { get; set; } } //Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasOne<StudentAddress>(s => s.Address) .WithOne(ad => ad.Student) .HasForeignKey<StudentAddress>(ad => ad.AddressOfStudentId); } public DbSet<Student> Students { get; set; } public DbSet<StudentAddress> StudentAddresses { get; set; }
多对多:
// 实体 public class StudentCourse { public int StudentId { get; set; } public Student Student { get; set; } public int CourseId { get; set; } public Course Course { get; set; } } public class Student { public int StudentId { get; set; } public string Name { get; set; } public IList<StudentCourse> StudentCourses { get; set; } } public class Course { public int CourseId { get; set; } public string CourseName { get; set; } public string Description { get; set; } public IList<StudentCourse> StudentCourses { get; set; } } // Fluent API modelBuilder.Entity<StudentCourse>().HasKey(sc => new { sc.SId, sc.CId }); modelBuilder.Entity<StudentCourse>() .HasOne<Student>(sc => sc.Student) .WithMany(s => s.StudentCourses) .HasForeignKey(sc => sc.SId); modelBuilder.Entity<StudentCourse>() .HasOne<Course>(sc => sc.Course) .WithMany(s => s.StudentCourses) .HasForeignKey(sc => sc.CId);
排除实体和属性--NotMapped
// 实体 排除entity public class Blog { public int BlogId { get; set; } public string Url { get; set; } public BlogMetadata Metadata { get; set; } } [NotMapped] public class BlogMetadata { public DateTime LoadedFromDatabase { get; set; } } 排除属性 public class Blog { public int BlogId { get; set; } public string Url { get; set; } [NotMapped] public DateTime LoadedFromDatabase { get; set; } } //Fluent API 排除entity protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Ignore<BlogMetadata>(); } 排除属性 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Ignore(b => b.LoadedFromDatabase); }
最大长度--MaxLength (Fluent API 中没有MinLength)
//实体 public class Blog { public int BlogId { get; set; } [MaxLength(500)] public string Url { get; set; } } //Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Url) .HasMaxLength(500); }
防并发:Timestamp 与ConcurrencyCheck
//实体 public class Person { public int PersonId { get; set; } [ConcurrencyCheck] public string LastName { get; set; } //10 .Timestamp 时间戳必须是byte[]类型的,防止并发,EF 的并发都是乐观的。例如同时改一条数据,别人在你之前提交 [Timestamp] public byte[] Timestamp { get; set; } } //Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(p => p.Timestamp) .IsRowVersion(); modelBuilder.Entity<Blog>().Property(b => b.Timestamp).IsRowVersion(); }
值转换
和Data Seeding 一起举例在进行数据库迁移时,EF会往数据库中插入一些数据
Data Seeding 这个是用来初始化数据用。
// 值类型转换 public class Blog { public int BlogId { get; set; } public string Url { get; set; } public EquineBeast Mount { get; set; } } public enum EquineBeast { Donkey, Mule, Horse, Unicorn } // fluent api protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder .Entity<Rider>() .Property(e => e.Mount) .HasConversion( v => v.ToString(), v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v)); // DATA SEEDING modelBuilder.Entity<Blog>().HasData(new Blog { BlogId = 1, Url = "http://sample.com" }); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端