Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How does ASP.NET Core use EF to create a relational model

2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, I would like to share with you how ASP.NET Core uses EF to create a relational model. The content is detailed and the logic is clear. I believe most people still know too much about this, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

1. Relationship

A relationship defines the relationship between two entities. In a relational database, this is represented by a foreign key constraint.

two。 Term definition

There are many terms used to describe relationships:

Related entity: this is the entity that contains foreign key attributes. It is sometimes called a "child" of a relationship.

Principal entity: this is the entity that contains the primary / standby key attribute. Sometimes called the "parent" of a relationship.

Foreign key: relies on attributes in the entity to store the value of the principal key attribute associated with the entity.

Principal key: an attribute that uniquely identifies the principal entity. This could be a primary key or an alternate key.

Navigation attribute: an attribute defined on a principal and / or dependent entity that contains a reference to a related entity.

Collection navigation property: a navigation property that contains references to multiple related entities.

Reference navigation property: holds the navigation property of a reference to a single related entity.

Reverse navigation attributes: when discussing specific navigation properties, this term refers to the navigation properties on the other side of the relationship.

The following code list shows the one-to-many relationship Post with Blog

Post is a dependent entity

Blog is the principal entity

Post.BlogId is a foreign key

Blog.BlogId is the primary key (in this case the primary key, not the standby key)

Post.Blog is a reference navigation property

Blog.Posts is a collection navigation property

Post.Blog is the Blog.Posts reverse navigation property (and vice versa)

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;}} 3. Agreement

By convention, when navigation attributes are found on a type, a relationship is created. If the property points to a type that cannot be mapped to a scalar type by the current database provider, the property is considered a navigation property.

4. A fully defined relationship

The most common pattern of relationships is to define navigation attributes at both ends of the relationship and foreign key attributes in dependent entity classes.

If a pair of navigation properties are found between two types, they are configured as reverse navigation properties of the same relationship.

If the dependent entity contains an attribute named, or, the attribute will be configured as a foreign key.

Public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Navigation attributes public List Posts {get; set;}} public class Post {public int PostId {get; set;} public string Title {get; set;} public string Content {get; set;} / / Foreign key attributes public int BlogId {get; set;} / / reverse navigation attributes public Blog Blog {get; set }} 5. No foreign key attribute

Although it is recommended that foreign key attributes be defined in dependent entity classes, this is not required. If the foreign key attribute is not found, the shadow foreign key property is introduced with that name.

Public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Shadow navigation attributes public List Posts {get; set;}} public class Post {public int PostId {get; set;} public string Title {get; set;} public string Content {get; set;} / / Shadow reverse navigation attributes public Blog Blog {get; set;} 6. Single navigation attribute

Containing only one navigation attribute (no reverse navigation, no foreign key attribute) is sufficient to have a relationship defined by convention. You can also have a navigation property and a foreign key property.

Public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Shadow navigation properties public List Posts {get; set;}} public class Post {public int PostId {get; set;} public string Title {get; set;} public string Content {get; set;} 7. Data annotation

You can use two data annotations to configure relationships [ForeignKey] and [InverseProperty]. These items are provided in the System.ComponentModel.DataAnnotations.Schema namespace.

7.1ForeignKey

You can use data annotations to configure the properties of the application as the foreign key property of a given relationship. Typically, this action is performed when a foreign key property is not found by convention.

Namespace EFModeling.DataAnnotations.Relationships.ForeignKey {class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set;}} # region Entities public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Navigation Properties public List Posts {get; set }} public class Post {public int PostId {get; set;} public string Title {get; set;} public string Content {get; set;} / / Foreign key public int BlogForeignKey {get; set;} / / set reverse navigation foreign key [ForeignKey ("BlogForeignKey")] public Blog Blog {get; set;}} # endregion} 7.2InverseProperty

You can use data annotations to configure how dependencies and navigation properties on the principal entity are matched. This is usually performed when there are multiple navigation attribute pairs between two entity types.

Namespace EFModeling.DataAnnotations.Relationships.InverseProperty {class MyContext: DbContext {public DbSet Posts {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

To configure a relationship in a well-known API, first identify the navigation properties that make up the relationship. HasOne or HasMany identifies the navigation attribute on the entity type that you want to start configuring. The call is then linked to WithOne or WithMany to identify the reverse navigation. HasOne/WithOne is used to reference navigation properties, and HasMany / WithMany is used to collect navigation properties.

Namespace EFModeling.FluentAPI.Relationships.NoForeignKey {# region Model class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set;} protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () / / configure an one-to-many relationship. 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 single navigation attribute

If there is only one navigation property, use the no-parameter overload of WithOne and WithMany. This means that conceptually, there is a reference or collection on the other end of the relationship, but the entity class does not contain navigation attributes.

Namespace EFModeling.FluentAPI.Relationships.OneNavigation {# region Model class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set;} protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () / / configure many-to-one relationship. HasMany (b = > b.Posts) .WithOne () }} public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Navigation Properties 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

You can use API to configure the foreign key properties of the application.

Namespace EFModeling.Configuring.DataAnnotations.Samples.Relationships.ForeignKey {# region Model class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set } protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () / configure an one-to-many relationship. HasOne (p = > p.Blog) .WithMany (b = > b.Posts) / / configure a foreign key .HasForeignKey (p = > p.BlogForeignKey) }} public class Blog {public int BlogId {get; set;} public string Url {get; set;} / / Navigation Properties public List Posts {get; set;}} public class Post {public int PostId {get; set;} public string Title {get; set;} public string Content {get; set } / / Foreign key public int BlogForeignKey {get; set;} public Blog Blog {get; set;}} # endregion}

The following code list shows how to configure compound foreign keys:

Namespace EFModeling.Configuring.DataAnnotations.Samples.Relationships.CompositeForeignKey {# region Model class MyContext: DbContext {public DbSet Cars {get; set;} protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () / / configure compound primary key .HasKey (c = > new {c.State, c.LicensePlate}) ModelBuilder.Entity () / configure an one-to-many relationship. HasOne (s = > s.Car) .WithMany (c = > c.SaleHistory) / / configure foreign keys .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;} / / Navigation Properties public List SaleHistory {get; set;}} public class RecordOfSale {public int RecordOfSaleId {get; set;} public DateTime DateSold {get; set;} public decimal Price {get; set } / / State corresponds to CarState public string CarState {get; set;} / / LicensePlate corresponds to CarLicensePlate public string CarLicensePlate {get; set;} public Car Car {get; set;}} # endregion}

HasForeignKey (...) that you can use String overloading configures the shadow property as a foreign key. It is recommended that you explicitly add shadow attributes to the model before using them as foreign keys:

Class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set;} protected override void OnModelCreating (ModelBuilder modelBuilder) {/ / Add the shadow property to the model modelBuilder.Entity () / / configure foreign key .Property ("BlogForeignKey") / / Use the shadow property as a foreign key modelBuilder.Entity () / / configure an one-to-many relationship .HasOne (p = > p.Blog) .WithMany (b = > b.Posts) / / configure a foreign key .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 No navigation attribute

It is not necessary to provide navigation properties. You can provide foreign keys directly at one end of the relationship.

Namespace EFModeling.FluentAPI.Relationships.NoNavigation {# region Model class MyContext: DbContext {public DbSet Blogs {get; set;} public DbSet Posts {get; set } protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () / / configure an one-to-many relationship. HasOne () .WithMany () / configure a foreign key .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. Principal key

If you want the foreign key to refer to a property other than the primary key, you can use the familiar API to configure the principal key property of the relationship. The property configured as the principal key is automatically set as an alternate key.

Class MyContext: DbContext {public DbSet Cars {get; set;} protected override void OnModelCreating (ModelBuilder modelBuilder) {modelBuilder.Entity () .HasOne (s = > s.Car) .WithMany (c = > c.SaleHistory) .HasForeignKey (s = > s.CarLicensePlate) .Hasprinciple alKey (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;}}

The following code list shows how to configure a compound principal key:

Class MyContext: DbContext {public DbSet Cars {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. Required and optional relationship

You can use the familiar API to configure whether the relationship is required or optional. Ultimately, this controls whether the foreign key property is required or optional. This is useful when using shadow state foreign keys. If there is a foreign key attribute in the entity class, the requiredness of the relationship depends on whether the foreign key attribute is required or optional.

Class MyContext: DbContext {public DbSet Blogs {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. Cascade deletion

You can explicitly configure cascading deletion behavior for a given relationship using the familiar API.

Class MyContext: DbContext {public DbSet Blogs {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. Other relationship models 12.1 one-to-one

An one-to-many relationship has a reference navigation property on both sides. They follow the same conventions as one-to-many relationships, but introduce unique indexes on foreign key properties to ensure that only one dependency is related to each principal.

12.1.1 data Notes 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

Use the HasOne and WithOne methods when configuring relationships with API. When configuring foreign keys, you need to specify dependent entity types. Note the generic parameters provided in the following list, HasForeignKey. In an one-to-many relationship, it is clear that the entity with reference navigation is a dependency and the entity with a collection is the principal. But this is not an one-to-one relationship, so you need to define it explicitly.

Class MyContext: DbContext {public DbSet Blogs {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 many-to-many

At present, many-to-many relationships are not supported, and there are no entity classes to represent join tables. However, you can represent many-to-many relationships by including entity classes that join tables and mapping two different one-to-many relationships.

Class MyContext: DbContext {public DbSet Posts {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;}} these are all the contents of the article "how ASP.NET Core uses EF to create a relational model". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report