網(wǎng)站首頁 編程語言 正文
1.關(guān)系
關(guān)系定義兩個實體之間的關(guān)系。在關(guān)系型數(shù)據(jù)庫中,這由外鍵約束表示。
2.術(shù)語定義
有許多術(shù)語用于描述關(guān)系:
- 相關(guān)實體:這是包含外鍵屬性的實體。有時稱為關(guān)系的"子級"。
- 主體實體:這是包含主/備用鍵屬性的實體。有時稱為關(guān)系的 "父項"。
- 外鍵:依賴實體中的屬性,用于存儲與實體相關(guān)的主體鍵屬性的值。
- 主體密鑰:唯一標識主體實體的屬性。這可能是主鍵或備用密鑰。
- 導航屬性:在主體和/或從屬實體上定義的屬性,該屬性包含對相關(guān)實體的引用。
- 集合導航屬性:一個導航屬性,其中包含對多個相關(guān)實體的引用。
- 引用導航屬性:保存對單個相關(guān)實體的引用的導航屬性。
- 反向?qū)Ш綄傩裕河懻撎囟▽Ш綄傩詴r,此術(shù)語是指關(guān)系另一端的導航屬性。
下面的代碼列表顯示了與之間Blog的一對多關(guān)系Post
- Post是依賴實體
- Blog是主體實體
- Post.BlogId為外鍵
- Blog.BlogId是主體鍵(在這種情況下是主鍵,而不是備用鍵)
- Post.Blog是一個引用導航屬性
- Blog.Posts是集合導航屬性
- Post.Blog是的Blog.Posts反向?qū)Ш綄傩裕ǚ粗嗳唬?/li>
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public ListPosts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
3.約定
按照約定,當發(fā)現(xiàn)類型上有導航屬性時,將創(chuàng)建關(guān)系。如果屬性指向的類型不能由當前的數(shù)據(jù)庫提供程序映射為標量類型,則該屬性視為一個導航屬性。
4.完全定義的關(guān)系
關(guān)系最常見的模式是在關(guān)系兩端定義導航屬性,在依賴實體類中定義外鍵屬性。
如果在兩個類型之間找到一對導航屬性,則這些屬性將配置為同一關(guān)系的反向?qū)Ш綄傩浴?br>如果依賴實體包含名為
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public ListPosts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } //外鍵屬性 public int BlogId { get; set; } //反向?qū)Ш綄傩? public Blog Blog { get; set; } }
5.無外鍵屬性
盡管建議在依賴實體類中定義外鍵屬性,但這并不是必需的。如果未找到外鍵屬性,則會以該名稱
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //陰影導航屬性 public ListPosts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } //陰影反向?qū)Ш綄傩? public Blog Blog { get; set; } }
6.單個導航屬性
只包含一個導航屬性(無反向?qū)Ш?,沒有外鍵屬性)就足以具有約定定義的關(guān)系。 還可以有一個導航屬性和一個外鍵屬性。
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //陰影導航屬性 public ListPosts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } }
7.數(shù)據(jù)注釋
可以使用兩個數(shù)據(jù)批注來配置關(guān)系[ForeignKey]和[InverseProperty]。System.ComponentModel.DataAnnotations.Schema命名空間中提供了這些項。
7.1ForeignKey
你可以使用數(shù)據(jù)批注來配置應用程序作給定關(guān)系的外鍵屬性的屬性。通常,當不按約定發(fā)現(xiàn)外鍵屬性時,會執(zhí)行此操作。
namespace EFModeling.DataAnnotations.Relationships.ForeignKey { class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } } #region Entities public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } //外鍵 public int BlogForeignKey { get; set; } //設(shè)置反向?qū)Ш酵怄I [ForeignKey("BlogForeignKey")] public Blog Blog { get; set; } } #endregion }
7.2InverseProperty
您可以使用數(shù)據(jù)批注來配置依賴項和主體實體上的導航屬性如何配對。這通常在兩個實體類型之間存在多個導航屬性對時執(zhí)行。
namespace EFModeling.DataAnnotations.Relationships.InverseProperty { class MyContext : DbContext { public DbSetPosts { get; set; } public DbSet Users { get; set; } } #region Entities public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int AuthorUserId { get; set; } public User Author { get; set; } public int ContributorUserId { get; set; } public User Contributor { get; set; } } public class User { public string UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } [InverseProperty("Author")] public List AuthoredPosts { get; set; } [InverseProperty("Contributor")] public List ContributedToPosts { get; set; } } #endregion }
8.Fluent API
若要在熟知的API中配置關(guān)系,請首先標識構(gòu)成關(guān)系的導航屬性。HasOne或HasMany標識要開始配置的實體類型上的導航屬性。然后,將調(diào)用鏈接到WithOne或WithMany以標識反向?qū)Ш?。HasOne/WithOne用于引用導航屬性,HasMany / WithMany用于集合導航屬性。
namespace EFModeling.FluentAPI.Relationships.NoForeignKey { #region Model class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () //配置一對多關(guān)系 .HasOne(p => p.Blog) .WithMany(b => b.Posts); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public Blog Blog { get; set; } } #endregion }
8.1單個導航屬性
如果只有一個導航屬性,則用WithOne、WithMany的無參數(shù)重載。這表示在概念上,關(guān)系的另一端有一個引用或集合,但實體類中不包含導航屬性。
namespace EFModeling.FluentAPI.Relationships.OneNavigation { #region Model class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () //配置多對一關(guān)系 .HasMany(b => b.Posts) .WithOne(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } } #endregion }
8.2ForeignKey
你可以使用API來配置應用程序的外鍵屬性。
namespace EFModeling.Configuring.DataAnnotations.Samples.Relationships.ForeignKey { #region Model class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () //配置一對多關(guān)系 .HasOne(p => p.Blog) .WithMany(b => b.Posts) //配置外鍵 .HasForeignKey(p => p.BlogForeignKey); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } //外鍵 public int BlogForeignKey { get; set; } public Blog Blog { get; set; } } #endregion }
下面的代碼列表演示如何配置復合外鍵:
namespace EFModeling.Configuring.DataAnnotations.Samples.Relationships.CompositeForeignKey { #region Model class MyContext : DbContext { public DbSetCars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () //配置復合主鍵 .HasKey(c => new { c.State, c.LicensePlate }); modelBuilder.Entity () //配置一對多關(guān)系 .HasOne(s => s.Car) .WithMany(c => c.SaleHistory) //配置外鍵 .HasForeignKey(s => new { s.CarState, s.CarLicensePlate }); } } public class Car { public string State { get; set; } public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } //導航屬性 public List SaleHistory { get; set; } } public class RecordOfSale { public int RecordOfSaleId { get; set; } public DateTime DateSold { get; set; } public decimal Price { get; set; } //State對應CarState public string CarState { get; set; } //LicensePlate 對應CarLicensePlate public string CarLicensePlate { get; set; } public Car Car { get; set; } } #endregion }
您可以使用的HasForeignKey(...)字符串重載將影子屬性配置為外鍵。建議先將影子屬性顯式添加到模型,然后再將其用作外鍵:
class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // Add the shadow property to the model modelBuilder.Entity () //配置外鍵 .Property ("BlogForeignKey"); // Use the shadow property as a foreign key modelBuilder.Entity () //配置一對多關(guān)系 .HasOne(p => p.Blog) .WithMany(b => b.Posts) //配置外鍵 .HasForeignKey("BlogForeignKey"); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public Blog Blog { get; set; } }
8.3無導航屬性
不一定需要提供導航屬性。你可以直接在關(guān)系的一端提供外鍵。
namespace EFModeling.FluentAPI.Relationships.NoNavigation { #region Model class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () //配置一對多關(guān)系 .HasOne () .WithMany() //配置外鍵 .HasForeignKey(p => p.BlogId); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } } #endregion }
9.主體密鑰
如果你希望外鍵引用主鍵之外的屬性,則可以使用熟知的API來配置關(guān)系的主體鍵屬性。 配置為主體密鑰的屬性將自動設(shè)置為備用密鑰。
class MyContext : DbContext { public DbSetCars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasOne(s => s.Car) .WithMany(c => c.SaleHistory) .HasForeignKey(s => s.CarLicensePlate) .HasPrincipalKey(c => c.LicensePlate); } } public class Car { public int CarId { get; set; } public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } public List SaleHistory { get; set; } } public class RecordOfSale { public int RecordOfSaleId { get; set; } public DateTime DateSold { get; set; } public decimal Price { get; set; } public string CarLicensePlate { get; set; } public Car Car { get; set; } }
下面的代碼列表演示如何配置復合主體鍵:
class MyContext : DbContext { public DbSetCars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasOne(s => s.Car) .WithMany(c => c.SaleHistory) .HasForeignKey(s => new { s.CarState, s.CarLicensePlate }) .HasPrincipalKey(c => new { c.State, c.LicensePlate }); } } public class Car { public int CarId { get; set; } public string State { get; set; } public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } public List SaleHistory { get; set; } } public class RecordOfSale { public int RecordOfSaleId { get; set; } public DateTime DateSold { get; set; } public decimal Price { get; set; } public string CarState { get; set; } public string CarLicensePlate { get; set; } public Car Car { get; set; } }
10.必需和可選的關(guān)系
您可以使用熟知的API來配置是必需的還是可選的關(guān)系。最終,這會控制外鍵屬性是必需的還是可選的。當使用陰影狀態(tài)外鍵時,這非常有用。如果實體類中具有外鍵屬性,則關(guān)系的requiredness取決于外鍵屬性是必需還是可選。
class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasOne(p => p.Blog) .WithMany(b => b.Posts) .IsRequired(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public Blog Blog { get; set; } }
11.級聯(lián)刪除
您可以使用熟知的API顯式配置給定關(guān)系的級聯(lián)刪除行為。
class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasOne(p => p.Blog) .WithMany(b => b.Posts) .OnDelete(DeleteBehavior.Cascade); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int? BlogId { get; set; } public Blog Blog { get; set; } }
12.其他關(guān)系模式
12.1一對一
一對多關(guān)系在兩側(cè)都有一個引用導航屬性。它們遵循與一對多關(guān)系相同的約定,但在外鍵屬性上引入了唯一索引,以確保只有一個依賴項與每個主體相關(guān)。
12.1.1數(shù)據(jù)注釋
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public BlogImage BlogImage { get; set; } } public class BlogImage { public int BlogImageId { get; set; } public byte[] Image { get; set; } public string Caption { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
12.1.2Fluent API
使用API 配置關(guān)系時,請使用HasOne和WithOne方法。配置外鍵時,需要指定依賴實體類型,請注意以下列表HasForeignKey中提供的泛型參數(shù)。在一對多關(guān)系中,可以清楚地表明具有引用導航的實體是依賴項,并且具有集合的實體是主體。但這并不是一對一的關(guān)系,因此需要顯式定義它。
class MyContext : DbContext { public DbSetBlogs { get; set; } public DbSet BlogImages { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasOne(p => p.BlogImage) .WithOne(i => i.Blog) .HasForeignKey (b => b.BlogForeignKey); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public BlogImage BlogImage { get; set; } } public class BlogImage { public int BlogImageId { get; set; } public byte[] Image { get; set; } public string Caption { get; set; } public int BlogForeignKey { get; set; } public Blog Blog { get; set; } }
12.2多對多
目前尚不支持多對多關(guān)系,沒有實體類來表示聯(lián)接表。但是,您可以通過包含聯(lián)接表的實體類并映射兩個不同的一對多關(guān)系,來表示多對多關(guān)系。
class MyContext : DbContext { public DbSetPosts { get; set; } public DbSet Tags { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity () .HasKey(pt => new { pt.PostId, pt.TagId }); modelBuilder.Entity () .HasOne(pt => pt.Post) .WithMany(p => p.PostTags) .HasForeignKey(pt => pt.PostId); modelBuilder.Entity () .HasOne(pt => pt.Tag) .WithMany(t => t.PostTags) .HasForeignKey(pt => pt.TagId); } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public List PostTags { get; set; } } public class Tag { public string TagId { get; set; } public List PostTags { get; set; } } public class PostTag { public int PostId { get; set; } public Post Post { get; set; } public string TagId { get; set; } public Tag Tag { get; set; } }
原文鏈接:https://www.cnblogs.com/wzk153/p/11730933.html
相關(guān)推薦
- 2022-07-14 C#把dll分別放在指定的文件夾的方法步驟_C#教程
- 2022-04-21 Python數(shù)據(jù)類型中的元組Tuple_python
- 2022-05-13 Headless Chrom自動化工具詳解
- 2021-11-08 Android如何實現(xiàn)時間線效果_Android
- 2022-03-06 C#多種操作excel的方法比較_C#教程
- 2022-10-20 Swift協(xié)議Protocol介紹_Swift
- 2021-12-10 addEventListener的執(zhí)行函數(shù)使用具名函數(shù)并傳參,可使用removeEventListe
- 2022-07-12 element表格 頻繁切換維度,導致表頭渲染有誤
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支