欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Entity?Framework配置關(guān)系

 更新時(shí)間:2022年06月13日 15:17:44   作者:springsnow  
這篇文章介紹了Entity?Framework配置關(guān)系的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、Has方法與With方法

如:A類必須包含B類一個(gè)不為null的實(shí)例,而B類可選擇時(shí)候包含A類一個(gè)實(shí)例。

A.HasRequired(a => a.B).WithOptional(b => b.A);

1、Has方法:

  • HasOptional:前者(A)可以包含后者(B)一個(gè)實(shí)例或者為null
  • HasRequired:前者必須包含后者一個(gè)不為null的實(shí)例
  • HasMany:前者包含后者實(shí)例的集合

2、With方法:

  • WithOptional:后者(B)可以包含前者(A)一個(gè)實(shí)例或者null
  • WithRequired:后者必須包含前者一個(gè)不為null的實(shí)例
  • WithMany:后者包含前者實(shí)例的集合

二、一對(duì)一關(guān)系:

兩個(gè)類中先都要配置相應(yīng)的引用屬性

1、DataAnnotations數(shù)據(jù)標(biāo)注的方式

用到ForeignKey外鍵標(biāo)注。

public class Person
{
    public int PersonId { get; set; }
    public int SocialSecurityNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
    public PersonPhoto Photo { get; set; }
}

public class PersonPhoto
{
    [Key, ForeignKey("PhotoOf")] //注意:PersonPhoto表中的PersonId既是外鍵也必須是主鍵
    public int PersonId { get; set; }
    public byte[] Photo { get; set; }
    public string Caption { get; set; }
    public Person PhotoOf { get; set; }
}

2、Fluent API方式

(1)1:0..1關(guān)系

PersonPhoto必須屬于一個(gè)Person,但是Person不一定有PersonPhoto, 此種情況下Person是一定存在的,所以它是主從關(guān)系主的一方。

modelBuilder.Entity<Person>().HasOptional(t => t.Photo).WithRequired(t => t.PhotoOf); 
modelBuilder.Entity<PersonPhoto>().HasRequired(p => p.PhotoOf).WithOptional(p => p.Photo);

(2)1:1 關(guān)系

PersonPhoto必須屬于一個(gè)Person,Person也必須有PersonPhoto。

modelBuilder.Entity<Person>().HasRequired(p => p.Photo ).WithRequiredPrincipal();
modelBuilder.Entity<PersonPhoto>().HasRequired(t => t.PhotoOf).WithRequiredDependent(t => t.Photo);

此種情況下,兩個(gè)都一定存在,要確定主從關(guān)系,需要使用WithRequiredPrincipal或WithRequiredDependent。

  • 如果你選擇 WithOptionalPrincipal(當(dāng)前實(shí)體為主體;目標(biāo)實(shí)體為依賴對(duì)象)PersonPhoto表中有一個(gè)外鍵,指向Person表的主鍵。
  • 如果你選擇 WithOptionalDependen t則相反(當(dāng)前實(shí)體為依賴對(duì)象;目標(biāo)實(shí)體為主體)則代表Person表中有一個(gè)外鍵,指向PersonPhoto表的主鍵,

Person表可以沒有對(duì)應(yīng)的PersonPhoto表數(shù)據(jù),但是PersonPhoto表每一條數(shù)據(jù)都必須對(duì)應(yīng)一條Person表數(shù)據(jù)。意思就是人可以沒有照片,但是有的照片必須屬于某個(gè)人。

三、一對(duì)多關(guān)系:

1、DataAnnotations方式

一對(duì)多關(guān)系很多情況下我們都不需要特意的去配置,通過一些引用屬性、導(dǎo)航屬性等檢測到模型之間的關(guān)系,自動(dòng)為我們生成外鍵。

public class Destination
{//景點(diǎn)類
    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 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 Target { get; set; }
}

Code First觀察到Lodging類中有一個(gè)對(duì)Destination的引用屬性,或者Destination中又有一個(gè)集合導(dǎo)航屬性Lodgings,因此推測出Destination與Lodging的關(guān)系是一對(duì)多關(guān)系.

所以在生成的數(shù)據(jù)庫中為自動(dòng)為Lodging表生成外鍵:外鍵名:Target_DestinationId

2、更改外鍵的nullable屬性和外鍵的名字

默認(rèn)情況下,如果你的外鍵命名是規(guī)范的話,Code First自動(dòng)會(huì)將該屬性設(shè)置為外鍵,不再自動(dòng)創(chuàng)建一個(gè)外鍵。 
規(guī)范命名是指符合:命名為如下的形式:(在這里目標(biāo)類型就是Destination)

  • [目標(biāo)類型的主鍵名]:如:DestinationId
  • [目標(biāo)類型名稱]+[目標(biāo)類型主鍵名稱]:如:DestinationDestinationId
  • [導(dǎo)航屬性名稱]+[目標(biāo)類型主鍵名稱]:如:TargetDestinationId

如:DestinationId屬性自動(dòng)作為主鍵。

public class Lodging
{
        public int? DestinationId { get; set; }
        public Destination Destination { get; set; }
}

當(dāng)然我們也可以自己在類中增加一個(gè)外鍵。

1、使用Data Annotations指定外鍵:

注意ForeignKey位置的不同,其后帶的參數(shù)也不同。

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

public Destination Target { get; set; }

public int TarDestinationId { get; set; }

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

2、用Fluent API指定外鍵:

如果實(shí)體類沒定義AccommodationId,那么可以使用Map方法直接指定外鍵名:.Map(s => s.MapKey("AccommodationId")) 
(1)Lodging一定歸屬于一個(gè)Destination,這種關(guān)系是1:n。

modelBuilder.Entity<Destination>().HasMany(d => d.Lodgings).WithRequired(l => l.Destination).Map(l => l.MapKey("DestinationId"));
modelBuilder.Entity<Lodgings>().HasRequired(l => l.Target).WithMany(d=>d.Lodgings).HasForeignKey(l => l.TarDestinationId);

(2)Post可以單獨(dú)存在,不用歸屬于Blog,這種關(guān)系是0..1:n。

modelBuilder.Entity<Destination>().HasMany(d => d.Lodgings).WithOptional(l => l.Destination).Map(l => l.MapKey("DestinationId")); 
modelBuilder.Entity<Lodgings>().HasOptional(l => l.Target).WithMany(d => d.Lodgings).HasForeignKey(l => l.TarDestinationId);

3、對(duì)同一實(shí)體多個(gè)引用的情況

public class Person
{
    public int PersonID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List PrimaryContactFor { get; set; }
    public List SecondaryContactFor { 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 Target { get; set; }
    //第一聯(lián)系人
    public Person PrimaryContact { get; set; }
    //第二聯(lián)系人
    public Person SecondaryContact { get; set; }
}

Lodging(旅店)有兩個(gè)對(duì)Person表的引用,分別是PrimaryContact與SecondaryContact, 
同時(shí),在Person表中也有對(duì)這兩個(gè)聯(lián)系人的導(dǎo)航:PrimaryContactFor與SecondaryContactFor。

因?yàn)樵谶@兩個(gè)表之間存在多個(gè)一對(duì)多關(guān)系,所以Code First無法處理這種情況。 
為了讓Code First知道它們之間的對(duì)應(yīng)關(guān)系,在這里要用到逆導(dǎo)航屬性來解決。

(1)使用Data Annotations:

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

(2)或使用Fluent API:

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

在生成的數(shù)據(jù)庫中為自動(dòng)為Lodging表生成兩個(gè)外鍵:PrimaryContact _PersonID 和SecondaryPersonID

4、級(jí)聯(lián)刪除

1、如果兩個(gè)表之間存在一對(duì)多關(guān)系,Code First默認(rèn)會(huì)開啟兩個(gè)表之間的級(jí)聯(lián)刪除功能 
數(shù)據(jù)庫里可以可視化的設(shè)置不級(jí)聯(lián)刪除,F(xiàn)luent API配置此外鍵關(guān)系時(shí)可以設(shè)置不級(jí)聯(lián)刪除:

this.HasMany(d => d.Lodgings).WithRequired(l => l.Destination).Map(l => l.MapKey("DestinationId")) //一對(duì)多并指定外鍵名
.WillCascadeOnDelete(false);   // 關(guān)閉級(jí)聯(lián)刪除

2、也可以在上下文的OnModelCreating方法中移除這個(gè)默認(rèn)約定

modelBuilder.Conventions.Remove();

再需要開啟級(jí)聯(lián)刪除,則可以在FluentAPI關(guān)系映射中用. WillCascadeOnDelete(true) 單獨(dú)開啟

四、多對(duì)多關(guān)系

如果有兩個(gè)類中,各自都是導(dǎo)航屬性指向另一個(gè)類,Code First會(huì)認(rèn)為這兩個(gè)類之間是多對(duì)多關(guān)系,例如:

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 Activities { get; set; }
}

public class Activity
{
    public int ActivityId { get; set; }
    [Required, MaxLength(50)]
    public string Name { get; set; }
    public List Trips { get; set; }
}

Code First生成了一張中間表ActivityTrips,將另外兩張表的主鍵都作為外鍵關(guān)聯(lián)到了中間表上面。 
中間表中字段的命名默認(rèn)為"[目標(biāo)類型名稱]_[目標(biāo)類型鍵名稱]".Activity_ActivityId 和Trip_TripId 
并且也作為這個(gè)新的連接表的聯(lián)合主鍵。

指定表名

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

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

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

到此這篇關(guān)于Entity Framework配置關(guān)系的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論