Общие сведения о связях

В этом документе представлено простое введение в представление связей в объектных моделях и реляционных базах данных, включая сопоставление EF Core между двумя.

Связи в объектных моделях

Связь определяет, как две сущности связаны друг с другом. Например, при моделировании записей в блоге каждая запись связана с блогом, на котором она опубликована, и блог связан со всеми записями, опубликованными в этом блоге.

В объектно-ориентированном языке, например C#, блог и запись обычно представлены двумя классами: Blog и Post. Например:

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }
}
public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }
}

В приведенных выше классах нет ничего, чтобы указать, что Blog и Post связаны. Это можно добавить в объектную модель, добавив ссылку из Post объекта Blog , на которую она опубликована:

public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateOnly PublishedOn { get; set; }
    public bool Archived { get; set; }

    public Blog Blog { get; set; }
}

Аналогичным образом, противоположное направление одной и той же связи может быть представлено как коллекция Post объектов на каждом из Blogних:

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}

Это подключение от BlogPost и Post обратно к ней Blog называется "связью" в EF Core.

Важно!

Одна связь обычно проходит в любом направлении. В этом примере это свойство осуществляется PostBlog.Posts через Blog свойство и обратно Post через BlogPost.Blog свойство. Это одна связь, а не две.

Совет

В EF Core Blog.Posts свойства Post.Blog называются навигациями.

Связи в реляционных базах данных

Реляционные базы данных представляют отношения с помощью внешних ключей. Например, с помощью SQL Server или SQL Azure можно использовать следующие таблицы для представления наших Post и Blog классов:

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [PublishedOn] datetime2 NOT NULL,
    [Archived] bit NOT NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);

CREATE TABLE [Blogs] (
    [Id] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [SiteUri] nvarchar(max) NULL,
    CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]));

В этой реляционной модели PostsBlogs каждая таблица получает столбец "первичный ключ". Значение первичного ключа однозначно идентифицирует каждую запись или блог. Кроме того, в Posts таблице указан столбец внешнего ключа. Столбец Blogs первичного Posts ключа ссылается на BlogId столбец Id внешнего ключа таблицы. Этот столбец является "ограниченным", таким образом, что любое значение в BlogId столбцеPosts должно соответствовать значению в столбце IdBlogs. Это совпадение определяет, с каким блогом связана каждая запись. Например, если BlogId значение в одной строке таблицы равно 7, то запись, представленная этой строкой Posts , публикуется в блоге с первичным ключом 7.

Сопоставление связей в EF Core

Сопоставление связей EF Core — это сопоставление первичного ключа или внешнего ключа, используемого в реляционной базе данных с ссылками между объектами, используемыми в объектной модели.

В самом базовом смысле это включает в себя:

  • Добавление свойства первичного ключа к каждому типу сущности.
  • Добавление свойства внешнего ключа в один тип сущности.
  • Связывание ссылок между типами сущностей с основными и внешними ключами для формирования единой конфигурации связи.

После внесения этого сопоставления EF изменяет значения внешнего ключа при необходимости при изменении ссылок между объектами и изменяет ссылки между объектами при необходимости при изменении значений внешнего ключа.

Примечание.

Первичные ключи используются для более чем связей сопоставления. Дополнительные сведения см. в разделе "Ключи ".

Например, указанные выше типы сущностей можно обновить с помощью свойств первичного и внешнего ключа:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Совет

Свойства первичного и внешнего ключа не должны быть общедоступными видимыми свойствами типа сущности. Однако даже если свойства скрыты, важно признать, что они по-прежнему существуют в модели EF.

Свойство первичного Blogключа , Blog.Idа также свойство внешнего ключа Post, Post.BlogIdзатем может быть связано со ссылками ("навигации") между типами сущностей (Blog.Posts и Post.Blog). Это делается автоматически EF при создании простой связи, как это, но также можно явно указать при переопределении OnModelCreating метода вашего DbContext. Например:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(e => e.Posts)
        .WithOne(e => e.Blog)
        .HasForeignKey(e => e.BlogId)
        .HasPrincipalKey(e => e.Id);
}

Теперь все эти свойства будут вести себя последовательно как представление одной связи между Blog и Post.

Подробнее

EF поддерживает множество различных типов связей с различными способами представления и настройки этих связей. Чтобы перейти к примерам различных типов связей, см. следующие сведения:

  • Связи "один ко многим", в которых одна сущность связана с любым количеством других сущностей.
  • Связи "один к одному", в которых одна сущность связана с другой одной сущностью.
  • Связи "многие ко многим", в которых любое количество сущностей связано с любым числом других сущностей.

Если вы не знакомы с EF, попробуйте примеры, связанные в указанных выше пунктах маркеров, является хорошим способом почувствовать, как работают отношения.

Дополнительные сведения о свойствах типов сущностей, участвующих в сопоставлении связей, см. в следующих статье:

Модели EF создаются с помощью трех механизмов: соглашений, атрибутов сопоставления и API построителя моделей. В большинстве примеров показан API построения модели. Дополнительные сведения о других вариантах см. в следующем разделе:

Важно!

API построения модели является окончательным источником истины для модели EF. Она всегда имеет приоритет над конфигурацией, обнаруженной по соглашению или заданным атрибутами сопоставления. Это также единственный механизм с полной точностью для настройки каждого аспекта модели EF.

К другим темам, связанным с отношениями, относятся следующие:

  • Каскадные удаления, описывающие автоматическое удаление связанных сущностей при SaveChanges вызове или SaveChangesAsync вызове.
  • Типы принадлежащих сущностей используют особый тип связи "владение", которая подразумевает более сильное соединение между двумя типами, чем "обычные" связи, рассмотренные здесь. Многие понятия, описанные здесь для обычных отношений, переносятся в собственные отношения. Однако собственные отношения также имеют собственное специальное поведение.

Совет

Ознакомьтесь с глоссарием терминов отношений при необходимости при чтении документации, чтобы понять используемую терминологию.

Использование связей

Связи, определенные в модели, можно использовать различными способами. Например: