RelacjeRelationships

Relacja definiuje sposób dwie jednostki powiązane są ze sobą.A relationship defines how two entities relate to each other. W relacyjnej bazie danych jest reprezentowane przez ograniczenie klucza obcego.In a relational database, this is represented by a foreign key constraint.

Uwaga

Większość przykładów w tym artykule umożliwiają zademonstrowania pojęć relacji jeden do wielu.Most of the samples in this article use a one-to-many relationship to demonstrate concepts. Zobacz przykłady relacji jeden do jednego i wiele do wielu inne wzorce relacji sekcji na końcu tego artykułu.For examples of one-to-one and many-to-many relationships see the Other Relationship Patterns section at the end of the article.

Definicje terminówDefinition of Terms

Istnieje wiele terminy używane do opisywania relacjiThere are a number of terms used to describe relationships

  • Jednostki zależne: jest to obiekt, który zawiera właściwości kluczy obcych.Dependent entity: This is the entity that contains the foreign key property(s). Czasami określane jako "podrzędne" w relacji.Sometimes referred to as the 'child' of the relationship.

  • Jednostka główna: to jednostka, która zawiera właściwości klucza podstawowego/alternatywny.Principal entity: This is the entity that contains the primary/alternate key property(s). Czasami określane jako "parent" w relacji.Sometimes referred to as the 'parent' of the relationship.

  • Klucz obcy: właściwości w jednostce zależne, który jest używany do przechowywania wartości właściwości klucza jednostki powiązanej jednostki.Foreign key: The property(s) in the dependent entity that is used to store the values of the principal key property that the entity is related to.

  • Klucz jednostki: właściwości, który unikatowo identyfikuje główną jednostki.Principal key: The property(s) that uniquely identifies the principal entity. Może to być kluczem podstawowym lub unikatowym.This may be the primary key or an alternate key.

  • Właściwość nawigacji: właściwości zdefiniowane w jednostce podmiotu zabezpieczeń i/lub zależne, który zawiera odwołania do powiązanych entity(s).Navigation property: A property defined on the principal and/or dependent entity that contains a reference(s) to the related entity(s).

    • Właściwości nawigacji kolekcji: właściwość nawigacji, który zawiera odwołania do wielu powiązanych jednostek.Collection navigation property: A navigation property that contains references to many related entities.

    • Odwoływać się do właściwości nawigacji: właściwość nawigacji, która zawiera odwołanie do pojedynczego obiektu pokrewnego.Reference navigation property: A navigation property that holds a reference to a single related entity.

    • Właściwość nawigacji odwrotność: Omawiając właściwości określonej nawigacji, określenie to odnosi się do właściwości nawigacji na końcu relacji.Inverse navigation property: When discussing a particular navigation property, this term refers to the navigation property on the other end of the relationship.

W poniższym fragmencie kodu przedstawiono relację jeden do wielu między Blog i PostThe following code listing shows a one-to-many relationship between Blog and Post

  • Post to jednostka zależnaPost is the dependent entity

  • Blog to jednostka głównaBlog is the principal entity

  • Post.BlogId jest to klucz obcyPost.BlogId is the foreign key

  • Blog.BlogId to klucz jednostki (w tym przypadku jest kluczem podstawowym, a nie klucza alternatywnego)Blog.BlogId is the principal key (in this case it is a primary key rather than an alternate key)

  • Post.Blog jest to właściwość nawigacji odwołaniaPost.Blog is a reference navigation property

  • Blog.Posts jest to właściwość nawigacji kolekcjiBlog.Posts is a collection navigation property

  • Post.Blog jest właściwość nawigacji odwrotność Blog.Posts (i na odwrót)Post.Blog is the inverse navigation property of Blog.Posts (and vice versa)

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; }
}

KonwencjeConventions

Zgodnie z Konwencją będzie można utworzyć relacji, po wykryte na typ właściwości nawigacji.By convention, a relationship will be created when there is a navigation property discovered on a type. Właściwość jest traktowana jako właściwość nawigacji, jeśli nie można zamapować typu, który wskazuje jako typ skalarny przez bieżącego dostawcę bazy danych.A property is considered a navigation property if the type it points to can not be mapped as a scalar type by the current database provider.

Uwaga

Relacje, które zostały wykryte przez Konwencję zawsze będą ukierunkowane na klucz podstawowy jednostki głównej.Relationships that are discovered by convention will always target the primary key of the principal entity. Pod kątem klucza alternatywnego, należy wykonać dodatkowe czynności konfiguracyjne przy użyciu interfejsu API Fluent.To target an alternate key, additional configuration must be performed using the Fluent API.

W pełni zdefiniowanych relacjiFully Defined Relationships

Najczęstszym wzorcem dla relacji jest zdefiniowane na obu końcach relacji i właściwości klucza obcego zdefiniowanej w klasie jednostki zależne właściwości nawigacji.The most common pattern for relationships is to have navigation properties defined on both ends of the relationship and a foreign key property defined in the dependent entity class.

  • Jeśli para właściwości nawigacji znajduje się między dwoma typami, następnie one zostaną skonfigurowane jako właściwości nawigacji odwrotność tej samej relacji.If a pair of navigation properties is found between two types, then they will be configured as inverse navigation properties of the same relationship.

  • Jeśli jednostka zależna zawiera właściwość o nazwie <primary key property name>, <navigation property name><primary key property name>, lub <principal entity name><primary key property name> , a następnie zostaną skonfigurowane jako klucza obcego.If the dependent entity contains a property named <primary key property name>, <navigation property name><primary key property name>, or <principal entity name><primary key property name> then it will be configured as the foreign key.

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; }
}

Ostrzeżenie

Czy wiele właściwości nawigacji zdefiniowane między dwoma typami (czyli więcej niż jedną parę distinct źródłem, które wskazują na siebie nawzajem), następnie relacje nie zostanie utworzony zgodnie z Konwencją i trzeba będzie ręcznie skonfigurować je do identyfikowania sposób, w jaki pary właściwości nawigacji.If there are multiple navigation properties defined between two types (that is, more than one distinct pair of navigations that point to each other), then no relationships will be created by convention and you will need to manually configure them to identify how the navigation properties pair up.

Nie właściwości klucza obcegoNo Foreign Key Property

Mimo że zaleca się mieć właściwość klucza obcego zdefiniowanej w klasie jednostki zależne, nie jest wymagana.While it is recommended to have a foreign key property defined in the dependent entity class, it is not required. Jeśli zostanie znalezione nie właściwość klucza obcego, zostaną wprowadzone właściwości klucza obcego w tle o nazwie <navigation property name><principal key property name> (zobacz właściwości w tle Aby uzyskać więcej informacji).If no foreign key property is found, a shadow foreign key property will be introduced with the name <navigation property name><principal key property name> (see Shadow Properties for more information).

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; }
}

Właściwości pojedynczej wartościSingle Navigation Property

Łącznie z tylko jedną właściwość nawigacji (nie odwrotność nawigacji i nie właściwości klucza obcego) jest wystarczający, aby mieć relacji zdefiniowanych przez Konwencję.Including just one navigation property (no inverse navigation, and no foreign key property) is enough to have a relationship defined by convention. Można również mieć właściwości pojedynczej wartości i właściwości klucza obcego.You can also have a single navigation property and a foreign key property.

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; }
}

Usuwanie kaskadoweCascade Delete

Zgodnie z Konwencją, usuwanie kaskadowe zostanie ustawiony Cascade dla relacji wymagane i ClientSetNull dla relacji opcjonalne.By convention, cascade delete will be set to Cascade for required relationships and ClientSetNull for optional relationships. Kaskadowe oznacza, że jednostki zależne również zostaną usunięte.Cascade means dependent entities are also deleted. ClientSetNull oznacza, że jednostki zależne, które nie są ładowane do pamięci pozostaną bez zmian i muszą być ręcznie usunięty lub poinformowani o prawidłową jednostkę główną.ClientSetNull means that dependent entities that are not loaded into memory will remain unchanged and must be manually deleted, or updated to point to a valid principal entity. W przypadku jednostek, które są ładowane do pamięci programu EF Core będzie podejmować próby równa właściwości klucza obcego o wartości null.For entities that are loaded into memory, EF Core will attempt to set the foreign key properties to null.

Zobacz relacje wymaganych i opcjonalnych sekcji różnicę między relacje wymaganych i opcjonalnych.See the Required and Optional Relationships section for the difference between required and optional relationships.

Zobacz usuwanie kaskadowe więcej szczegółów na temat różnych Usuń zachowania i wartości domyślne używane przez Konwencję.See Cascade Delete for more details about the different delete behaviors and the defaults used by convention.

Adnotacje danychData Annotations

Istnieją dwa adnotacji danych, które mogą być używane do konfigurowania relacji [ForeignKey] i [InverseProperty].There are two data annotations that can be used to configure relationships, [ForeignKey] and [InverseProperty].

[Klucza obcego][ForeignKey]

Korzystanie z adnotacji danych, aby skonfigurować, których właściwość powinna być używana jako właściwość klucza obcego dla danej relacji.You can use the Data Annotations to configure which property should be used as the foreign key property for a given relationship. Zazwyczaj jest to wykonywane, gdy właściwość klucza obcego nie został odnaleziony przez Konwencję.This is typically done when the foreign key property is not discovered by convention.

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; }
}

Porada

[ForeignKey] Adnotacji można umieścić we właściwości nawigacji, albo w relacji.The [ForeignKey] annotation can be placed on either navigation property in the relationship. Nie musi przejść na właściwość nawigacji w klasie jednostki zależne.It does not need to go on the navigation property in the dependent entity class.

[InverseProperty][InverseProperty]

Korzystanie z adnotacji danych, aby skonfigurować sposób pary właściwości nawigacji jednostki zależnej i głównej.You can use the Data Annotations to configure how navigation properties on the dependent and principal entities pair up. Zazwyczaj jest to wykonywane, gdy istnieje więcej niż jedną parę właściwości nawigacji między dwoma typami encji.This is typically done when there is more than one pair of navigation properties between two entity types.

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; }
}

Interfejs Fluent APIFluent API

Aby skonfigurować relację w interfejsie API Fluent, możesz rozpocząć, określając właściwości nawigacji, które tworzą relacji.To configure a relationship in the Fluent API, you start by identifying the navigation properties that make up the relationship. HasOne lub HasMany identyfikuje właściwość nawigacji typu jednostki, rozpoczynamy od konfiguracji na.HasOne or HasMany identifies the navigation property on the entity type you are beginning the configuration on. Można następnie połączyć w łańcuch po wywołaniu WithOne lub WithMany do identyfikowania odwrotność nawigacji.You then chain a call to WithOne or WithMany to identify the inverse navigation. HasOne/WithOne są używane dla właściwości nawigacji odwołania i HasMany / WithMany są używane dla właściwości nawigacji kolekcji.HasOne/WithOne are used for reference navigation properties and HasMany/WithMany are used for collection navigation properties.

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; }
}

Właściwości pojedynczej wartościSingle Navigation Property

Jeśli masz tylko jedną właściwość nawigacji, a następnie istnieją przeciążenia bez parametrów WithOne i WithMany.If you only have one navigation property then there are parameterless overloads of WithOne and WithMany. Oznacza to, że ma pod względem koncepcyjnym odwołanie lub kolekcji na końcu relacji, ale nie ma właściwości nawigacji zawarta w klasie jednostki.This indicates that there is conceptually a reference or collection on the other end of the relationship, but there is no navigation property included in the entity class.

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; }
}

Klucz obcyForeign Key

Interfejs Fluent API umożliwiają skonfigurowanie, których właściwość powinna być używana jako właściwość klucza obcego dla danej relacji.You can use the Fluent API to configure which property should be used as the foreign key property for a given relationship.

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; }
}

W poniższym fragmencie kodu przedstawiono sposób konfigurowania złożonego klucza obcego.The following code listing shows how to configure a composite foreign key.

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; }

    public string CarState { get; set; }
    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

Można użyć ciągu przeciążenia HasForeignKey(...) do skonfigurowania właściwości w tle jako klucz obcy (zobacz właściwości w tle Aby uzyskać więcej informacji).You can use the string overload of HasForeignKey(...) to configure a shadow property as a foreign key (see Shadow Properties for more information). Zalecane jest jawne dodanie właściwości w tle do modelu, zanim użyjesz go jako klucza obcego (jak pokazano poniżej).We recommend explicitly adding the shadow property to the model before using it as a foreign key (as shown below).

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; }
}

Klucz jednostkiPrincipal Key

Jeśli chcesz, aby klucz obcy, aby odwoływać się do właściwości innego niż klucz podstawowy, można użyć interfejsu API Fluent do skonfigurowania właściwości klucza podmiotu zabezpieczeń dla relacji.If you want the foreign key to reference a property other than the primary key, you can use the Fluent API to configure the principal key property for the relationship. Właściwość, którą można skonfigurować jako głównej będą kluczowe automatycznie należy skonfigurować jako klucza alternatywnego (zobacz klucze alternatywne Aby uzyskać więcej informacji).The property that you configure as the principal key will automatically be setup as an alternate key (see Alternate Keys for more information).

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; }
}

W poniższym fragmencie kodu przedstawiono sposób konfigurowania złożony klucz jednostki.The following code listing shows how to configure a composite principal key.

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; }
}

Ostrzeżenie

Kolejność, w której zostaną określone jednostki właściwości klucza musi być zgodna kolejność, w którym są określone w kluczu obcym.The order in which you specify principal key properties must match the order in which they are specified for the foreign key.

Relacje wymagane i opcjonalneRequired and Optional Relationships

Aby określić, czy relacja jest wymagane lub opcjonalne, można użyć interfejsu API Fluent.You can use the Fluent API to configure whether the relationship is required or optional. Ostatecznie to określa, czy właściwość klucza obcego jest wymagane lub opcjonalne.Ultimately this controls whether the foreign key property is required or optional. Jest to najbardziej przydatne, korzystając z kluczem obcym stanu w tle.This is most useful when you are using a shadow state foreign key. Jeśli masz właściwości klucza obcego w klasie jednostki, a następnie requiredness relacji jest określana na podstawie tego, czy właściwość klucza obcego jest wymagane lub opcjonalne (zobacz wymagane i opcjonalne właściwości Aby uzyskać więcej informacji informacje o).If you have a foreign key property in your entity class then the requiredness of the relationship is determined based on whether the foreign key property is required or optional (see Required and Optional properties for more information).

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; }
}

Usuwanie kaskadoweCascade Delete

Interfejs Fluent API umożliwiają skonfigurowanie jawnie zachowanie usuwanie kaskadowe określonej relacji.You can use the Fluent API to configure the cascade delete behavior for a given relationship explicitly.

Zobacz usuwanie kaskadowe sekcji Zapisywanie danych szczegółowe omówienie każdej z nich.See Cascade Delete on the Saving Data section for a detailed discussion of each option.

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; }
}

Inne wzorce relacjiOther Relationship Patterns

Jeden do jednegoOne-to-one

Relacje jeden-do-jednego ma odwołanie do właściwości nawigacji po obu stronach.One to one relationships have a reference navigation property on both sides. Używają tej samej Konwencji co relacji jeden do wielu, ale unikatowy indeks został wprowadzony na właściwość klucza obcego, aby upewnić się, że tylko jeden zależnych od powiązany jest każdy podmiot zabezpieczeń.They follow the same conventions as one-to-many relationships, but a unique index is introduced on the foreign key property to ensure only one dependent is related to each principal.

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; }
}

Uwaga

EF wybrać jeden z jednostki, które jest zależne od oparte na możliwość wykrywania właściwości klucza obcego.EF will choose one of the entities to be the dependent based on its ability to detect a foreign key property. Jeśli problem jednostki jest wybierany jako zależnych od ustawień lokalnych, można użyć Fluent API, aby rozwiązać ten problem.If the wrong entity is chosen as the dependent, you can use the Fluent API to correct this.

Podczas konfigurowania relacja z interfejsem API Fluent, możesz użyć HasOne i WithOne metody.When configuring the relationship with the Fluent API, you use the HasOne and WithOne methods.

Podczas konfigurowania klucza obcego, należy określić typ jednostki zależne - Zwróć uwagę, parametr generyczny udostępniane HasForeignKey na liście poniżej.When configuring the foreign key you need to specify the dependent entity type - notice the generic parameter provided to HasForeignKey in the listing below. W przypadku relacji jeden do wielu jest jasne, czy jednostka z nawigacją odwołanie jest zależnych od ustawień lokalnych, jak i z kolekcji jest podmiot zabezpieczeń.In a one-to-many relationship it is clear that the entity with the reference navigation is the dependent and the one with the collection is the principal. Ale to nie jest tak w przypadku relacji jeden do jednego — dlatego trzeba jawnie zdefiniować go.But this is not so in a one-to-one relationship - hence the need to explicitly define it.

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; }
}

Wiele do wieluMany-to-many

Relacje wiele do wielu, bez klasę jednostki, do reprezentowania tabelę sprzężenia nie są jeszcze obsługiwane.Many-to-many relationships without an entity class to represent the join table are not yet supported. Jednak może reprezentować relacji wiele do wielu, umieszczając klasę jednostki dla tabeli sprzężenia i dwie oddzielne relacje jeden do wielu mapowania.However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.

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(t => new { t.PostId, t.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; }
}