第十六节: EF的CodeFirst模式通过Fluent API修改默认协定
一. 簡(jiǎn)介
?1. 優(yōu)先級(jí):Fluent API > data annotations > default conventions.
?2. 所有的Fluent API配置都要在 OnModelCreating這個(gè)重寫方法中進(jìn)行
?3. 常見的配置:
?① 獲取表對(duì)應(yīng)的配置根: var stu =modelBuilder.Entity<XXX>();
?② 設(shè)置主鍵:HasKey<string>(s => s.studentKey);
?③ 獲取屬性:stu.Property(p => p.stuName)
?④ 設(shè)置可空或非空:IsRequired和IsOptional
? ⑤ 設(shè)置最大值:HasMaxLength
?⑥ 修改屬性名→修改屬性的次序→修改屬性對(duì)應(yīng)的數(shù)據(jù)庫類型:HasColumnName→HasColumnOrder→HasColumnType
?⑦ 修改表名:ToTable
?4. 可以建立多個(gè)Fluent API的配置文件,然后通過 modelBuilder.Configurations.Add(new XXX());添加到一起
PS:或者利用這句話???modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());? ? ?把所有的配置文件一次性全部加進(jìn)來
二. 代碼實(shí)戰(zhàn)
1 public class Student52 {3 //主鍵聲明4 public string studentKey { get; set; }5 6 //非空聲明7 public string stuName { get; set; }8 9 //最大長(zhǎng)度 10 public string stuTxt1 { get; set; } 11 12 //最大長(zhǎng)度和最小長(zhǎng)度 13 public string stuTxt2 { get; set; } 14 15 //設(shè)置為時(shí)間戳 16 public byte[] rowVersion { get; set; } 17 18 //并發(fā)檢查 19 public string stuTxt3 { get; set; } 20 21 //public virtual StudentAddress5 stuAddress5 { get; set; } 22 } 23 public class StudentAddress5 24 { 25 //既是主鍵、又是外鍵 26 public string stuAddressId { get; set; } 27 28 //設(shè)置映射數(shù)據(jù)庫中表的列名 29 public string stuAddressName { get; set; } 30 31 //設(shè)置映射數(shù)據(jù)庫中表的列名、順序、類型 32 public string stuAddrssName2 { get; set; } 33 34 //不映射數(shù)據(jù) 35 public string addressNum { get; set; } 36 37 //不映射數(shù)據(jù) 38 public string txt1 { get { return stuAddrssName2; } } 39 40 //不映射數(shù)據(jù) 41 public string _txt2 = "1"; 42 public string txt2 { set { _txt2 = value; } } 43 44 //public virtual Student5 stu { get; set; } 45 } 46 47 /// <summary> 48 /// Game實(shí)體,與其它兩個(gè)沒有什么直接關(guān)系,單純的為了演示, Fluent API的配置,可以根據(jù)實(shí)體進(jìn)行拆分 49 /// 文件來配置,方便管理 50 /// </summary> 51 public class Game 52 { 53 public int GameId { get; set; } 54 55 public string GameName { get; set; } 56 } 1 /// <summary>2 /// Game實(shí)體的配置文件3 /// </summary>4 public class GameConfiguration : EntityTypeConfiguration<Game>5 {6 public GameConfiguration()7 {8 this.HasKey(p => p.GameId);9 10 this.Property(p => p.GameName).HasMaxLength(10).IsRequired(); 11 } 12 } 1 public class dbContext5 : DbContext2 {3 public dbContext5()4 : base("name=dbContext5")5 {6 7 }8 9 public DbSet<Student5> Student5 { get; set; } 10 11 public DbSet<StudentAddress5> StudentAddress5 { get; set; } 12 13 14 protected override void OnModelCreating(DbModelBuilder modelBuilder) 15 { 16 //所有的FluentAPI均在方法中進(jìn)行重寫 17 18 //一. 屬性層次上的設(shè)置 19 var stu = modelBuilder.Entity<Student5>(); 20 var stuAddress = modelBuilder.Entity<StudentAddress5>(); 21 22 //1. 設(shè)置主鍵 23 stu.HasKey<string>(s => s.studentKey); 24 stuAddress.HasKey<string>(s => s.stuAddressId); //為什么需要?jiǎng)討B(tài)設(shè)置主鍵,有待研究?? 25 26 //2. 設(shè)置非空 (擴(kuò)展:IsOptional 設(shè)置可空) 27 stu.Property(p => p.stuName).IsRequired(); 28 29 //3. 設(shè)置最大值(不能設(shè)置最小值) 30 stu.Property(p => p.stuTxt1).HasMaxLength(10); 31 32 33 //4. 修改列的名稱、排序、類型 34 stuAddress.Property(p => p.stuAddrssName2).HasColumnName("myAddress2").HasColumnOrder(1).HasColumnType("varchar"); 35 36 //5.修改表名 37 stu.Map<Student5>(c => 38 { 39 c.ToTable("MyStudent"); 40 41 }); 42 43 //6.將一個(gè)實(shí)體映射成多張表,并分別給其命名 44 //stuAddress.Map<StudentAddress5>(c => 45 //{ 46 // c.Properties(p => new 47 // { 48 // p.stuAddressId, 49 // p.stuAddressName 50 // }); 51 // c.ToTable("MyStuAddress1"); 52 //}).Map<StudentAddress5>(c => 53 //{ 54 // c.Properties(p => new 55 // { 56 // p.stuAddressId, 57 // p.stuAddrssName2 58 // }); 59 // c.ToTable("MyStuAddress2"); 60 //}); 61 62 63 64 65 //三. 將Game實(shí)體的配置添加進(jìn)來 66 modelBuilder.Configurations.Add(new GameConfiguration()); 67 68 base.OnModelCreating(modelBuilder); 69 } 70 } 1 <!--正宗的CodeFirst Fluent API--> 2 <add name="dbContext5" connectionString="data source=localhost;initial catalog=CodeFirstDB5;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" /> 3三. 總結(jié)
? 無論是DataAnnotation還是Fluent API,都會(huì)發(fā)現(xiàn)一個(gè)現(xiàn)象,當(dāng)數(shù)據(jù)庫結(jié)構(gòu)發(fā)生變化的時(shí)候,就會(huì)拋出異常,不得不把數(shù)據(jù)庫刪除,重新生成,這樣就會(huì)導(dǎo)致原數(shù)據(jù)庫中的數(shù)據(jù)丟失,在實(shí)際開發(fā)中,顯然是不可取的。那么為什么會(huì)拋異常呢?怎么解決這個(gè)數(shù)據(jù)丟失的問題呢?詳見下一個(gè)章節(jié):數(shù)據(jù)庫初始化策略和數(shù)據(jù)遷移。
總結(jié)
以上是生活随笔為你收集整理的第十六节: EF的CodeFirst模式通过Fluent API修改默认协定的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#多线程编程系列(二)- 线程基础
- 下一篇: 12万买“坦克300” 新款哈弗大狗上市