Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O EF Core usa um modelo de metadados para descrever como os tipos de entidade do aplicativo são mapeados para o banco de dados subjacente. Esse modelo é criado usando um conjunto de convenções – heurísticas que buscam padrões comuns. Em seguida, o modelo pode ser personalizado usando atributos de mapeamento (também conhecidos como anotações de dados) e/ou chamadas para os ModelBuilder métodos (também conhecidos como API fluente),OnModelCreatingambos substituirão a configuração executada por convenções.
A maior parte da configuração pode ser aplicada a um modelo direcionado a qualquer armazenamento de dados. Os provedores também podem habilitar a configuração específica para um armazenamento de dados específico e também podem ignorar a configuração que não tem suporte ou não é aplicável. Para obter a documentação sobre a configuração específica do provedor, consulte a seção Provedores de banco de dados.
Dica
Você pode exibir os exemplos deste artigo no GitHub.
Usar a API fluente para configurar um modelo
Você pode sobrescrever o método OnModelCreating em seu contexto derivado e usar a API fluente para configurar o seu modelo. Esse é o método de configuração mais poderoso e permite que a configuração seja especificada sem modificar as classes de entidade. A configuração de API fluente tem a precedência mais alta e substituirá convenções e anotações de dados. A configuração é aplicada na ordem em que os métodos são chamados e, se houver conflitos, a chamada mais recente substituirá a configuração especificada anteriormente.
using Microsoft.EntityFrameworkCore;
namespace EFModeling.EntityProperties.FluentAPI.Required;
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
#region Required
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.IsRequired();
}
#endregion
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Dica
Para aplicar a mesma configuração a vários objetos no modelo, consulte a configuração em massa.
Configuração de agrupamento
Para reduzir o tamanho do método, toda a OnModelCreating configuração de um tipo de entidade pode ser extraída para uma classe separada implementando IEntityTypeConfiguration<TEntity>.
public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
public void Configure(EntityTypeBuilder<Blog> builder)
{
builder
.Property(b => b.Url)
.IsRequired();
}
}
Em seguida, basta invocar o método Configure do OnModelCreating.
new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());
Aplicando todas as configurações em uma montagem
É possível aplicar todas as configurações especificadas em tipos que implementam IEntityTypeConfiguration em um determinado assembly.
modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);
Observação
A ordem na qual as configurações serão aplicadas é indefinida, portanto, esse método só deve ser usado quando a ordem não importa.
Usando EntityTypeConfigurationAttribute em tipos de entidade
Em vez de chamar Configureexplicitamente, um EntityTypeConfigurationAttribute pode ser colocado no tipo de entidade de modo que o EF Core possa encontrar e usar a configuração apropriada. Por exemplo:
[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Isbn { get; set; }
}
Esse atributo significa que o EF Core usará a implementação especificada IEntityTypeConfiguration sempre que o Book tipo de entidade for incluído em um modelo. O tipo de entidade é incluído em um modelo usando um dos mecanismos normais. Por exemplo, criando uma DbSet<TEntity> propriedade para o tipo de entidade:
public class BooksContext : DbContext
{
public DbSet<Book> Books { get; set; }
//...
Ou registrando-o em OnModelCreating:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>();
}
Observação
EntityTypeConfigurationAttribute os tipos não serão descobertos automaticamente em um assembly. Os tipos de entidade devem ser adicionados ao modelo antes que o atributo seja descoberto nesse tipo de entidade.
Usar anotações de dados para configurar um modelo
Você também pode aplicar determinados atributos ( conhecidos como Anotações de Dados) às suas classes e propriedades. As anotações de dados substituirão as convenções, mas serão substituídas pela configuração da API fluente.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace EFModeling.EntityProperties.DataAnnotations.Annotations;
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
[Table("Blogs")]
public class Blog
{
public int BlogId { get; set; }
[Required]
public string Url { get; set; }
}
Convenções embutidas
O EF Core inclui muitas convenções de criação de modelos habilitadas por padrão. Você pode encontrar todas elas na lista de classes que implementam a IConvention interface. No entanto, essa lista não inclui convenções introduzidas por provedores de banco de dados e plug-ins de terceiros.
Os aplicativos podem remover ou substituir qualquer uma dessas convenções, bem como adicionar novas convenções personalizadas que aplicam a configuração para padrões que não são reconhecidos pelo EF por padrão.
Dica
O código mostrado abaixo vem de ModelBuildingConventionsSample.cs.
Removendo uma convenção existente
Às vezes, uma das convenções internas pode não ser apropriada para seu aplicativo, nesse caso, ela pode ser removida.
Dica
Se o modelo não usar atributos de mapeamento (também conhecidos como anotações de dados) para configuração, todas as convenções com o nome que terminam AttributeConvention podem ser removidas com segurança para acelerar a criação do modelo.
Exemplo: não criar índices para colunas de chave estrangeira
Geralmente faz sentido criar índices para colunas FK (chave estrangeira) e, portanto, há uma convenção interna para isso: ForeignKeyIndexConvention. Examinando a exibição de depuração de modelo para um Post tipo de entidade com relacionamentos com Blog e Author, podemos ver que dois índices são criados, um para o BlogId FK e outro para o AuthorId FK.
EntityType: Post
Properties:
Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AuthorId (no field, int?) Shadow FK Index
BlogId (no field, int) Shadow Required FK Index
Navigations:
Author (Author) ToPrincipal Author Inverse: Posts
Blog (Blog) ToPrincipal Blog Inverse: Posts
Keys:
Id PK
Foreign keys:
Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade
Indexes:
AuthorId
BlogId
No entanto, os índices têm sobrecarga e nem sempre pode ser apropriado criá-los para todas as colunas FK. Para isso, pode ForeignKeyIndexConvention ser removido ao compilar o modelo:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Remove(typeof(ForeignKeyIndexConvention));
}
Olhando para a exibição de depuração do modelo para Post agora, vemos que os índices dos FKs não foram criados.
EntityType: Post
Properties:
Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
AuthorId (no field, int?) Shadow FK
BlogId (no field, int) Shadow Required FK
Navigations:
Author (Author) ToPrincipal Author Inverse: Posts
Blog (Blog) ToPrincipal Blog Inverse: Posts
Keys:
Id PK
Foreign keys:
Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade
Quando desejado, os índices ainda podem ser criados explicitamente para colunas de chave estrangeira, usando IndexAttribute ou com configuração em OnModelCreating.
Exibição de depuração
A visualização de depuração do construtor de modelos pode ser acessada no depurador do seu IDE. Por exemplo, com o Visual Studio:
Ele também pode ser acessado diretamente a partir do código, por exemplo, para enviar a visualização de depuração para o console.
Console.WriteLine(context.Model.ToDebugString());
A exibição de depuração tem uma forma curta e uma forma longa. O formulário longo também inclui todas as anotações, que podem ser úteis se você precisar exibir metadados relacionais ou específicos do provedor. A exibição longa também pode ser acessada do código:
Console.WriteLine(context.Model.ToDebugString(MetadataDebugStringOptions.LongDefault));