日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EF Code First 学习笔记:关系

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EF Code First 学习笔记:关系 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一對多關系

項目中最常用到的就是一對多關系了。Code First對一對多關系也有著很好的支持。很多情況下我們都不需要特意的去配置,Code First就能通過一些引用屬性、導航屬性等檢測到模型之間的關系,自動為我們生成外鍵。觀察下面的類:

View Code public class Destination{public int DestinationId { get; set; }public string Name { get; set; }public string Country { get; set; }public string Description { get; set; }public byte[] Photo { get; set; }public List<Lodging> Lodgings { get; set; }}public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public bool IsResort { get; set; }public decimal MilesFromNearestAirport { get; set; }public Destination Destination { get; set; }}

Code First觀察到Lodging類中有一個對Destination的引用屬性,同時Destination中又有一個集合導航屬性Lodgings,因此推測出DestinationLodging的關系是一對多關系,所以在生成的數據庫中為自動為Lodging表生成外鍵:

其實,只要在一個類中存在引用屬性,即:

View Code public class Destination{public int DestinationId { get; set; }public string Name { get; set; }public string Country { get; set; }public string Description { get; set; }public byte[] Photo { get; set; }}public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public bool IsResort { get; set; }public decimal MilesFromNearestAirport { get; set; }public Destination Destination { get; set; }}

或一另一個類中存在導航屬性:

View Code public class Destination{public int DestinationId { get; set; }public string Name { get; set; }public string Country { get; set; }public string Description { get; set; }public byte[] Photo { get; set; }public List<Lodging> Lodgings { get; set; }}public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public bool IsResort { get; set; }public decimal MilesFromNearestAirport { get; set; }}

Code First都能檢測到它們之間一對多的關系,自動生成外鍵。

?指定外鍵

當然我們也可以自己在類中增加一個外鍵。默認情況下,如果你的外鍵命名是規范的話,Code First會將的該屬性設置為外鍵,不再自動創建一個外鍵,如:

View Code public class Destination{public int DestinationId { get; set; }public string Name { get; set; }public string Country { get; set; }public string Description { get; set; }public byte[] Photo { get; set; }public List<Lodging> Lodgings { get; set; }}public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public bool IsResort { get; set; }public decimal MilesFromNearestAirport { get; set; }//外鍵 public int TargetDestinationId { get; set; }public Destination Target { get; set; }}

規范命名是指符合:命名為“[目標類型的鍵名],[目標類型名稱]+[目標類型鍵名稱]”,或“[導航屬性名稱]+[目標類型鍵名稱]”的形式,在這里目標類型就是Destination,相對應的命名就是:DestinationId,DestinationDestinationId,TargetDestinationId

對于命名不規范的列,Code First會怎做呢?

比如我們將外鍵改為:

public int TarDestinationId { get; set; }

再重新生成數據庫:

可以看到Code First沒有識別到TarDestinationId是一個外鍵,于是自己創建了一個外鍵:Target_DestinationId。這時我們要告訴Code First該屬性是一個外鍵。

使用Data Annotations指定外鍵:

[ForeignKey("Target")]public int TarDestinationId { get; set; }public Destination Target { get; set; }

public int TarDestinationId { get; set; }[ForeignKey("TarDestinationId")]public Destination Target { get; set; }

注意ForeignKey位置的不同,其后帶的參數也不同。這樣,生成的數據庫就是我們所期望的了。Code First沒有再生成別的外鍵。

用Fluent API指定外鍵:

modelBuilder.Entity<Lodging>().HasRequired(p => p.Target).WithMany(l => l.Lodgings).HasForeignKey(p => p.TarDestinationId);

對同一個實體多個引用的情況

我們來考慮一下下面的情況:

View Code public class Lodging{public int LodgingId { get; set; }public string Name { get; set; }public string Owner { get; set; }public bool IsResort { get; set; }public decimal MilesFromNearestAirport { get; set; } public Destination Target { get; set; }//第一聯系人public Person PrimaryContact { get; set; }//第二聯系人public Person SecondaryContact { get; set; } } public class Person{public int PersonID { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public List<Lodging> PrimaryContactFor { get; set; }public List<Lodging> SecondaryContactFor { get; set; } }

Lodging(旅店)有兩個對Person表的引用,分別是PrimaryContact與SecondaryContact,同時,在Person表中也有對這兩個聯系人的導航:PrimaryContactFor與SecondaryContactFor。

看看Code First默認會生成怎樣的數據庫

天哪,竟然生成了四個外鍵。因為有兩套類型一樣的導航屬性與引用屬性,Code First無法確定它們之間的對應關系,就單獨為每個屬性都創建了一個關系。這肯定不是我們所期望的,為了讓Code First知道它們之間的對應關系,在這里要用到逆導航屬性來解決。

使用Data Annotations:

//第一聯系人[InverseProperty("PrimaryContactFor")] public Person PrimaryContact { get; set; }//第二聯系人[InverseProperty("SecondaryContactFor")] public Person SecondaryContact { get; set; }

或使用Fluent API:

modelBuilder.Entity<Lodging>().HasOptional(l => l.PrimaryContact).WithMany(p => p.PrimaryContactFor);
modelBuilder.Entity
<Lodging>().HasOptional(l=>l.SecondaryContact).WithMany(p=>p.SecondaryContactFor);

再重新生成數據庫,結果如圖:

多對多關系

如果有兩個類中,各自都是導航屬性指向另一個類,Code First會認為這兩個類之間是多對多關系,例如:

View Code public class Activity{public int ActivityId { get; set; }[Required, MaxLength(50)] public string Name { get; set; } public List<Trip> Trips { get; set; }}public class Trip{public int TripId{get;set;}public DateTime StartDate{get;set;}public DateTime EndDate { get; set; }public decimal CostUSD { get; set; }public byte[] RowVersion { get; set; }public List<Activity> Activities { get; set; }}

一個Trip類可以有一些Activites日程,而一個Activity日程又可以計劃好幾個trips(行程),顯然它們之間是多對多的關系。我們看看默認生成的數據庫是怎么樣的:

可以看到,Code First生成了一張中間表ActivityTrips,將另外兩張表的主鍵都作為外鍵關聯到了中間表上面。中間表中鍵的命名默認為"[目標類型名稱]_[目標類型鍵名稱]".

指定表名

如果我們想指定中間表的名稱和鍵名稱,我們可以用Fluent API來配置。

modelBuilder.Entity<Trip>().HasMany(t => t.Activities).WithMany(a => a.Trips).Map(m =>{m.ToTable("TripActivities");m.MapLeftKey("TripIdentifier");//對應Trip的主鍵m.MapRightKey("ActivityId");});

或:

modelBuilder.Entity<Activity>().HasMany(a => a.Trips).WithMany(t => t.Activities).Map(m =>{m.ToTable("TripActivities");m.MapLeftKey("ActivityId");//對應Activity的主鍵m.MapRightKey("TripIdentifier");});

一對一關系

如果我們要將兩個類配置為一對一關系,則兩個類中都要配置相應的引用屬性,如:

View Code public class Person{public int PersonId { get; set; }public int SocialSecurityNumber { get; set; }public string FirstName { get; set; }public string LastName { get; set; }1712813012public byte[] RowVersion { get; set; }public PersonPhoto Photo { get; set; }}public class PersonPhoto{[Key]public int PersonId { get; set; }public byte[] Photo { get; set; }public string Caption { get; set; }public Person PhotoOf { get; set; }}

我們為一個(Person)對應著一張相片(PersonPhoto),但如果根據這樣的模型生成數據庫為報錯:

無法確定類型“BreakAway.PersonPhoto”與“BreakAway.Person”之間的關聯的主體端。必須使用關系 Fluent API 或數據注釋顯式配置此關聯的主體端

因為Code First無法確認哪個是依賴類,必須使用Fluent API或Data Annotations進行顯示配置。

使用Data Annotations:

View Code public class Person{public int PersonId { get; set; }public int SocialSecurityNumber { get; set; }public string FirstName { get; set; }public string LastName { get; set; }1712813012public byte[] RowVersion { get; set; }public PersonPhoto Photo { get; set; }}public class PersonPhoto{[Key, ForeignKey("PhotoOf")]public int PersonId { get; set; }public byte[] Photo { get; set; }public string Caption { get; set; }public Person PhotoOf { get; set; }}

使用Fluent API:

modelBuilder.Entity<PersonPhoto>().HasRequired(p => p.PhotoOf).WithOptional(p => p.Photo);

?注意:PersonPhoto表中的PersonId既是外鍵也必須是主鍵

?

總結

以上是生活随笔為你收集整理的EF Code First 学习笔记:关系的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。