Partilhar via


Propriedades da entidade

Cada tipo de entidade em seu modelo tem um conjunto de propriedades, que o EF Core lerá e gravará do banco de dados. Se você estiver usando um banco de dados relacional, as propriedades da entidade serão mapeadas para colunas de tabela.

Propriedades incluídas e excluídas

Por convenção, todas as propriedades públicas com um getter e um setter serão incluídas no modelo.

As propriedades específicas podem ser excluídas da seguinte forma:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

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

Nomes das colunas

Por convenção, ao usar um banco de dados relacional, as propriedades da entidade são mapeadas para colunas de tabela com o mesmo nome da propriedade.

Se preferir configurar suas colunas com nomes diferentes, você pode fazer isso como o seguinte trecho de código:

public class Blog
{
    [Column("blog_id")]
    public int BlogId { get; set; }

    public string Url { get; set; }
}

Tipos de dados de coluna

Ao usar um banco de dados relacional, o provedor de banco de dados seleciona um tipo de dados com base no tipo .NET da propriedade. Ele também leva em conta outros metadados, como ode comprimento máximo configurado, se a propriedade faz parte de uma chave primária, etc.

Por exemplo, o provedor do SQL Server mapeia DateTime propriedades para datetime2(7) colunas e string propriedades para nvarchar(max) colunas (ou para nvarchar(450), para propriedades que são usadas como uma chave).

Você também pode configurar suas colunas para especificar um tipo de dados exato para uma coluna. Por exemplo, o código a seguir configura Url como uma cadeia de caracteres não-unicode com comprimento máximo de 200 e Rating como decimal com precisão de 5 e escala de 2:

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

    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }

    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
}

Comprimento máximo

A configuração de um comprimento máximo fornece uma dica ao provedor de banco de dados sobre o tipo de dados de coluna apropriado a ser escolhido para uma determinada propriedade. O comprimento máximo só se aplica a tipos de dados de matriz, como string e byte[].

Observação

O Entity Framework não faz nenhuma validação do comprimento máximo antes de passar dados para o provedor. Cabe ao provedor ou armazenamento de dados validar, se apropriado. Por exemplo, ao direcionar o SQL Server, exceder o comprimento máximo resultará em uma exceção, pois o tipo de dados da coluna subjacente não permitirá que dados em excesso sejam armazenados.

No exemplo a seguir, configurar um comprimento máximo de 500 fará com que uma coluna do tipo nvarchar(500) seja criada no SQL Server:

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

    [MaxLength(500)]
    public string Url { get; set; }
}

Precisão e Escala

Alguns tipos de dados relacionais suportam as facetas de precisão e escala; Eles controlam quais valores podem ser armazenados e quanto armazenamento é necessário para a coluna. Os tipos de dados que suportam precisão e escala dependem da base de dados, mas na maioria das bases de dados os tipos decimal e DateTime suportam essas facetas. Para decimal propriedades, a precisão define o número máximo de dígitos necessários para expressar qualquer valor que a coluna conterá, e a escala define o número máximo de casas decimais necessárias. Para propriedades DateTime, a precisão define o número máximo de dígitos necessários para expressar frações de segundos, e a escala não é usada.

Observação

O Entity Framework não faz nenhuma validação de precisão ou escala antes de passar dados para o provedor. Cabe ao provedor ou armazenamento de dados validar, conforme apropriado. Por exemplo, ao trabalhar com o SQL Server, uma coluna do tipo de dados datetime não permite definir a precisão, enquanto uma datetime2 pode ter precisão entre 0 e 7, inclusive.

No exemplo a seguir, configurar a propriedade Score para ter precisão 14 e escala 2 fará com que uma coluna do tipo decimal(14,2) seja criada no SQL Server, e configurar a propriedade LastUpdated para ter precisão 3 causará uma coluna do tipo datetime2(3):

public class Blog
{
    public int BlogId { get; set; }
    [Precision(14, 2)]
    public decimal Score { get; set; }
    [Precision(3)]
    public DateTime LastUpdated { get; set; }
}

A escala nunca é definida sem primeiro definir precisão, de modo que a Anotação de Dados para definir a escala é [Precision(precision, scale)].

Unicode

Em alguns bancos de dados relacionais, existem diferentes tipos para representar dados de texto Unicode e não-Unicode. Por exemplo, no SQL Server, nvarchar(x) é usado para representar dados Unicode em UTF-16, enquanto varchar(x) é usado para representar dados não-Unicode (mas consulte as notas sobre de suporte UTF-8 do SQL Server). Para bancos de dados que não suportam esse conceito, configurar isso não tem efeito.

As propriedades de texto são configuradas como Unicode por padrão. Você pode configurar uma coluna como não-Unicode da seguinte maneira:

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }

    [Unicode(false)]
    [MaxLength(22)]
    public string Isbn { get; set; }
}

Propriedades obrigatórias e opcionais

Uma propriedade é considerada opcional se for permitido que contenha null. Se null não é um valor válido a ser atribuído a uma propriedade, então ele é considerado uma propriedade necessária. Ao mapear para um esquema de banco de dados relacional, as propriedades necessárias são criadas como colunas não anuláveis e as propriedades opcionais são criadas como colunas anuláveis.

Convenções

Por convenção, uma propriedade cujo tipo .NET pode conter null será configurada como opcional, enquanto as propriedades cujo tipo .NET não pode conter null serão configuradas conforme necessário. Por exemplo, todas as propriedades com tipos de valor .NET (int, decimal, bool, etc.) são configuradas conforme necessário, e todas as propriedades com tipos de valor .NET anuláveis (int?, decimal?, bool?, etc.) são configuradas como opcionais.

O C# 8.0 introduziu um novo recurso chamado tipos de referência anuláveis (NRT), que permite que os tipos de referência sejam anotados, indicando se é válido que eles possam conter nulos ou não. Esse recurso é habilitado por padrão em novos modelos de projeto, mas permanece desabilitado em projetos existentes, a menos que seja explicitamente aceito. Os tipos de referência anuláveis afetam o comportamento do EF Core da seguinte maneira:

  • Se os tipos de referência anuláveis estiverem desabilitados, todas as propriedades com tipos de referência .NET serão configuradas como opcionais por convenção (por exemplo, string).
  • Se os tipos de referência anuláveis estiverem habilitados, as propriedades serão configuradas com base na anulabilidade em C# do seu tipo .NET: string? será configurado como opcional, mas string será configurado como obrigatório.

O exemplo a seguir mostra um tipo de entidade com propriedades obrigatórias e opcionais, com o recurso de referência nula desabilitado e habilitado:

public class CustomerWithoutNullableReferenceTypes
{
    public int Id { get; set; }

    [Required] // Data annotations needed to configure as required
    public string FirstName { get; set; }

    [Required] // Data annotations needed to configure as required
    public string LastName { get; set; }

    public string MiddleName { get; set; } // Optional by convention
}

O uso de tipos de referência anuláveis é recomendado, pois flui a anulabilidade expressa no código C# para o modelo do EF Core e para o banco de dados, e evita o uso da API Fluent ou Anotações de Dados para expressar o mesmo conceito duas vezes.

Observação

Tenha cuidado ao habilitar tipos de referência anuláveis em um projeto existente: as propriedades de tipo de referência que antes eram configuradas como opcionais agora serão configuradas conforme necessário, a menos que sejam explicitamente anotadas para serem anuláveis. Ao gerenciar um esquema de banco de dados relacional, isso pode fazer com que migrações sejam geradas que alteram a anulabilidade da coluna de banco de dados.

Para obter mais informações sobre tipos de referência anuláveis e como usá-los com o EF Core, consulte a página de documentação dedicada para este recurso.

Configuração explícita

Uma propriedade que seria opcional por convenção pode ser configurada para ser necessária da seguinte maneira:

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

    [Required]
    public string Url { get; set; }
}

Agrupamentos de colunas

Um agrupamento pode ser definido em colunas de texto, determinando como elas são comparadas e ordenadas. Por exemplo, o trecho de código a seguir configura uma coluna do SQL Server para não diferenciar maiúsculas de minúsculas:

modelBuilder.Entity<Customer>().Property(c => c.Name)
    .UseCollation("SQL_Latin1_General_CP1_CI_AS");

Se todas as colunas de um banco de dados precisarem usar um determinado agrupamento, defina o agrupamento no nível do banco de dados.

Informações gerais sobre o suporte do EF Core para agrupamentos podem ser encontradas na página de documentação de agrupamento .

Comentários da coluna

Você pode definir um comentário de texto arbitrário que é definido na coluna do banco de dados, permitindo que você documente seu esquema no banco de dados:

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

    [Comment("The URL of the blog")]
    public string Url { get; set; }
}

Ordem das colunas

Por padrão, ao criar uma tabela com Migrations, o EF Core ordena primeiro as colunas de chave primária, seguidas pelas propriedades do tipo de entidade e dos tipos de propriedade e, finalmente, as propriedades dos tipos base. No entanto, você pode especificar uma ordem de coluna diferente:

public class EntityBase
{
    [Column(Order = 0)]
    public int Id { get; set; }
}

public class PersonBase : EntityBase
{
    [Column(Order = 1)]
    public string FirstName { get; set; }

    [Column(Order = 2)]
    public string LastName { get; set; }
}

public class Employee : PersonBase
{
    public string Department { get; set; }
    public decimal AnnualSalary { get; set; }
}

A API Fluent pode ser usada para substituir a ordenação feita com atributos, incluindo a resolução de quaisquer conflitos quando atributos em propriedades diferentes especificam o mesmo número de ordem.

Observe que, no caso geral, a maioria dos bancos de dados só suporta colunas de ordenação quando a tabela é criada. Isso significa que o atributo de ordem de coluna não pode ser usado para reordenar colunas em uma tabela existente.