Типы сущностей

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

Включение типов в модель

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

В приведенном ниже примере кода включены все типы:

  • Blog включен, так как он предоставляется в свойстве DbSet в контексте.
  • Post включен, так как он обнаруживается через Blog.Posts свойство навигации.
  • AuditEntry так как он указан в OnModelCreating .
internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AuditEntry>();
    }
}

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 AuditEntry
{
    public int AuditEntryId { get; set; }
    public string Username { get; set; }
    public string Action { get; set; }
}

Исключение типов из модели

Если вы не хотите включать тип в модель, его можно исключить:

[NotMapped]
public class BlogMetadata
{
    public DateTime LoadedFromDatabase { get; set; }
}

Исключение из миграции

Примечание

Возможность исключения таблиц из миграции была введена в EF Core 5,0.

Иногда бывает полезно иметь один и тот же тип сущности, сопоставленный в нескольких DbContext типах. Это особенно справедливо при использовании ограниченныхконтекстов, для которых обычно используется отдельный DbContext тип для каждого ограниченного контекста.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<IdentityUser>()
        .ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}

При такой миграции конфигурации таблица не создается AspNetUsers , но IdentityUser по-прежнему включается в модель и может использоваться в обычном режиме.

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

Имя таблицы

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

Вы можете вручную настроить имя таблицы:

[Table("blogs")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Схема таблицы

При использовании реляционной базы данных таблицы — это соглашение, созданное в схеме базы данных по умолчанию. например, Microsoft SQL Server будет использовать dbo схему (SQLite не поддерживает схемы).

Можно настроить создание таблиц в определенной схеме следующим образом.

[Table("blogs", Schema = "blogging")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Вместо того чтобы указывать схему для каждой таблицы, можно также определить схему по умолчанию на уровне модели с помощью API-интерфейса Fluent:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("blogging");
}

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

Просмотр сопоставления

типы сущностей можно сопоставлять с представлениями базы данных с помощью API Fluent.

Примечание

EF предполагает, что представление, на которое имеется ссылка, уже существует в базе данных, оно не будет автоматически создаваться при миграции.

modelBuilder.Entity<Blog>()
    .ToView("blogsView", schema: "blogging");

Сопоставление с представлением приведет к удалению сопоставления таблицы по умолчанию, но начиная с EF 5,0 тип сущности также можно сопоставить с таблицей явным образом. В этом случае для запросов будет использоваться сопоставление запросов, а для обновлений будут использоваться сопоставления таблиц.

Совет

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

Сопоставление функций, возвращающих табличное значение

Можно сопоставлять тип сущности с возвращающей табличное значение функцией вместо таблицы в базе данных. Чтобы проиллюстрировать это, давайте определим другую сущность, которая представляет блог с несколькими записями. В этом примере сущность не имеет смысла, ноона не должна быть.

public class BlogWithMultiplePosts
{
    public string Url { get; set; }
    public int PostCount { get; set; }
}

Затем создайте в базе данных следующую функцию с табличным значением, которая возвращает только блоги с несколькими записями, а также число записей, связанных с каждым из этих блогов:

CREATE FUNCTION dbo.BlogsWithMultiplePosts()
RETURNS TABLE
AS
RETURN
(
    SELECT b.Url, COUNT(p.BlogId) AS PostCount
    FROM Blogs AS b
    JOIN Posts AS p ON b.BlogId = p.BlogId
    GROUP BY b.BlogId, b.Url
    HAVING COUNT(p.BlogId) > 1
)

Теперь сущность BlogWithMultiplePosts может быть сопоставлена с этой функцией следующим образом:

modelBuilder.Entity<BlogWithMultiplePosts>().HasNoKey().ToFunction("BlogsWithMultiplePosts");

Примечание

Чтобы связать сущность с возвращающей табличное значение функцией, функция должна быть без параметров.

Согласно соглашению, свойства сущности будут сопоставляться с соответствующими столбцами, возвращаемыми функцией. Если имена столбцов, возвращаемых ТАБЛИЧной функцией, отличаются от имен свойств сущностей, то столбцы сущности могут быть настроены с помощью HasColumnName метода, как и при сопоставлении с обычной таблицей.

Если тип сущности сопоставляется с функцией, возвращающей табличное значение, запрос:

var query = from b in context.Set<BlogWithMultiplePosts>()
            where b.PostCount > 3
            select new { b.Url, b.PostCount };

Преобразуется в следующий запрос SQL:

SELECT [b].[Url], [b].[PostCount]
FROM [dbo].[BlogsWithMultiplePosts]() AS [b]
WHERE [b].[PostCount] > 3

Комментарии к таблице

Можно задать произвольный текстовый комментарий, заданный для таблицы базы данных, что позволит документировать схему в базе данных:

Примечание

Установка комментариев с помощью заметок к данным была представлена в EF Core 5,0.

[Comment("Blogs managed on the website")]
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}