<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
關係定義兩個實體之間的關係。在關係型資料庫中,這由外來鍵約束表示。
有許多術語用於描述關係:
下面的程式碼列表顯示了與之間Blog的一對多關係Post
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> 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; } }
按照約定,當發現型別上有導航屬性時,將建立關係。如果屬性指向的型別不能由當前的資料庫提供程式對映為標量型別,則該屬性視為一個導航屬性。
關係最常見的模式是在關係兩端定義導航屬性,在依賴實體類中定義外來鍵屬性。
如果在兩個型別之間找到一對導航屬性,則這些屬性將設定為同一關係的反向導航屬性。
如果依賴實體包含名為<primary key property name>、<navigation property name><primary key property name>或<principal entity name><primary key property name>的屬性,則該屬性將被設定為外來鍵。
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List<Post> 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; } }
儘管建議在依賴實體類中定義外來鍵屬性,但這並不是必需的。如果未找到外來鍵屬性,則會以該名稱<navigation property name><principal key property name>引入陰影外來鍵屬性。
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //陰影導航屬性 public List<Post> 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; } }
只包含一個導航屬性(無反向導航,沒有外來鍵屬性)就足以具有約定定義的關係。 還可以有一個導航屬性和一個外來鍵屬性。
public class Blog { public int BlogId { get; set; } public string Url { get; set; } //陰影導航屬性 public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } }
可以使用兩個資料批註來設定關係[ForeignKey]和[InverseProperty]。System.ComponentModel.DataAnnotations.Schema名稱空間中提供了這些項。
你可以使用資料批註來設定應用程式作給定關係的外來鍵屬性的屬性。通常,當不按約定發現外來鍵屬性時,會執行此操作。
namespace EFModeling.DataAnnotations.Relationships.ForeignKey { class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } } #region Entities public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List<Post> 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; } //設定反向導航外來鍵 [ForeignKey("BlogForeignKey")] public Blog Blog { get; set; } } #endregion }
您可以使用資料批註來設定依賴項和主體實體上的導航屬性如何配對。這通常在兩個實體型別之間存在多個導航屬性對時執行。
namespace EFModeling.DataAnnotations.Relationships.InverseProperty { class MyContext : DbContext { public DbSet<Post> Posts { get; set; } public DbSet<User> 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<Post> AuthoredPosts { get; set; } [InverseProperty("Contributor")] public List<Post> ContributedToPosts { get; set; } } #endregion }
若要在熟知的API中設定關係,請首先標識構成關係的導航屬性。HasOne或HasMany標識要開始設定的實體型別上的導航屬性。然後,將呼叫連結到WithOne或WithMany以標識反向導航。HasOne/WithOne用於參照導航屬性,HasMany / WithMany用於集合導航屬性。
namespace EFModeling.FluentAPI.Relationships.NoForeignKey { #region Model class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() //設定一對多關係 .HasOne(p => p.Blog) .WithMany(b => b.Posts); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> 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 }
如果只有一個導航屬性,則用WithOne、WithMany的無引數過載。這表示在概念上,關係的另一端有一個參照或集合,但實體類中不包含導航屬性。
namespace EFModeling.FluentAPI.Relationships.OneNavigation { #region Model class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() //設定多對一關係 .HasMany(b => b.Posts) .WithOne(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } //導航屬性 public List<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } } #endregion }
你可以使用API來設定應用程式的外來鍵屬性。
namespace EFModeling.Configuring.DataAnnotations.Samples.Relationships.ForeignKey { #region Model class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() //設定一對多關係 .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<Post> 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 DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Car>() //設定複合主鍵 .HasKey(c => new { c.State, c.LicensePlate }); modelBuilder.Entity<RecordOfSale>() //設定一對多關係 .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<RecordOfSale> 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 DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // Add the shadow property to the model modelBuilder.Entity<Post>() //設定外來鍵 .Property<int>("BlogForeignKey"); // Use the shadow property as a foreign key modelBuilder.Entity<Post>() //設定一對多關係 .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<Post> 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; } }
不一定需要提供導航屬性。你可以直接在關係的一端提供外來鍵。
namespace EFModeling.FluentAPI.Relationships.NoNavigation { #region Model class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() //設定一對多關係 .HasOne<Blog>() .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 }
如果你希望外來鍵參照主鍵之外的屬性,則可以使用熟知的API來設定關係的主體鍵屬性。 設定為主體金鑰的屬性將自動設定為備用金鑰。
class MyContext : DbContext { public DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<RecordOfSale>() .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<RecordOfSale> 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 DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<RecordOfSale>() .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<RecordOfSale> 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; } }
您可以使用熟知的API來設定是必需的還是可選的關係。最終,這會控制外來鍵屬性是必需的還是可選的。當使用陰影狀態外來鍵時,這非常有用。如果實體類中具有外來鍵屬性,則關係的requiredness取決於外來鍵屬性是必需還是可選。
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .IsRequired(); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } public List<Post> 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; } }
您可以使用熟知的API顯式設定給定關係的級聯刪除行為。
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .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<Post> 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; } }
一對多關係在兩側都有一個參照導航屬性。它們遵循與一對多關係相同的約定,但在外來鍵屬性上引入了唯一索引,以確保只有一個依賴項與每個主體相關。
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; } }
使用API 設定關係時,請使用HasOne和WithOne方法。設定外來鍵時,需要指定依賴實體型別,請注意以下列表HasForeignKey中提供的泛型引數。在一對多關係中,可以清楚地表明具有參照導航的實體是依賴項,並且具有集合的實體是主體。但這並不是一對一的關係,因此需要顯式定義它。
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<BlogImage> BlogImages { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasOne(p => p.BlogImage) .WithOne(i => i.Blog) .HasForeignKey<BlogImage>(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; } }
目前尚不支援多對多關係,沒有實體類來表示聯接表。但是,您可以通過包含聯接表的實體類並對映兩個不同的一對多關係,來表示多對多關係。
class MyContext : DbContext { public DbSet<Post> Posts { get; set; } public DbSet<Tag> Tags { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<PostTag>() .HasKey(pt => new { pt.PostId, pt.TagId }); modelBuilder.Entity<PostTag>() .HasOne(pt => pt.Post) .WithMany(p => p.PostTags) .HasForeignKey(pt => pt.PostId); modelBuilder.Entity<PostTag>() .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<PostTag> PostTags { get; set; } } public class Tag { public string TagId { get; set; } public List<PostTag> 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; } }
到此這篇關於ASP.NET Core使用EF建立關係模型的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45