Temos uma classe Funcionario que herda de PessoaFisica. Quando a propriedade Cpf pertence à PessoaFisica, o EF Core entende que a configuração "mestra" dessa coluna deve vir da base.
Para resolver isso e declarar o índice na classe derivada (ou referenciando-a) sem conflitos, a melhor abordagem é utilizar a Fluent API dentro do seu DbContext.
A Solução com Fluent API
O segredo é configurar o índice diretamente no modelBuilder apontando para a classe Funcionario. O EF Core permite que você defina índices em classes derivadas, mesmo que a propriedade venha da base, desde que você não tente "reconfigurar" a propriedade em si (como mudar o nome da coluna ou o tipo) dentro do contexto da herança de forma conflitante.
No seu DbContext, faça o seguinte:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure a herança (Exemplo usando TPH - Tabela Única)
modelBuilder.Entity<PessoaFisica>()
.HasDiscriminator<string>("TipoPessoa");
// Configura o índice especificamente para Funcionario
modelBuilder.Entity<Funcionario>()
.HasIndex(f => f.Cpf)
.IsUnique(false); // Define como não único
}
Por que o erro acontece?
Se você estiver usando IEntityTypeConfiguration<Funcionario>, o erro pode aparecer se você tentar fazer algo como builder.Property(x => x.Cpf)... antes de definir o índice. O EF Core impede que você configure propriedades da base dentro do builder da derivada para evitar inconsistências no mapeamento da tabela.
Ao chamar .HasIndex(f => f.Cpf) diretamente, você está dizendo ao EF: "Eu sei que Cpf existe, eu só quero colocar um índice nele para este tipo de entidade".
Entendendo o Impacto no Banco de Dados
A forma como esse índice será criado no banco depende da sua estratégia de herança (TPH, TPT ou TPC).
TPH (Table Per Hierarchy - Padrão): Se todos estiverem na mesma tabela, o índice será criado na tabela única. Se você quer que o CPF seja não único apenas para funcionários, mas único para outros, você precisará de um Filtro de Índice (Filtered Index).
TPT (Table Per Type): Se cada classe tiver sua própria tabela, o índice será criado na tabela de
Funcionarios(se o campo estiver lá) ou na dePessoasFisicas.
Dica Pro: Índice Filtrado
Se você usa a estratégia de tabela única (TPH) e quer que o Cpf não seja único para Funcionario, mas seja único para o resto (como Cliente), você pode usar um filtro:
modelBuilder.Entity<PessoaFisica>()
.HasIndex(p => p.Cpf)
.HasFilter("[Cpf] IS NOT NULL AND [TipoPessoa] <> 'Funcionario'")
.IsUnique();
Isso garante a integridade dos dados para as outras classes enquanto permite a flexibilidade que você precisa para Funcionario.
Comentários