Error in running update-database migration

1

I'm trying to run the creation of my database, but I'm getting this error below and I'm not understanding why:

  

The type 'Client' can not be mapped as defined because it maps inherited properties from types that use entity splitting or another form of inheritance. Either choose a different inheritance mapping strategy or not to inherit properties, or change all types in the hierarchy to map inherited properties and not use splitting.

class Person

public abstract class Pessoa 
{
    public Pessoa()
    {
        IdPessoa = Guid.NewGuid();
        Enderecos = new List<Endereco>();
    }

    public Guid IdPessoa { get; set; }
    public  string Nome { get; set; }
    public  string Email { get; set; }
    public  DateTime DataDeCadastro { get; set; }
    public  bool Ativo { get; set; }
    public virtual ICollection<Endereco> Enderecos { get; set; }
}

Client Class

 public class Cliente: Pessoa, ISelfValidator
{
    public Cliente()
    {
        IdPessoa = Guid.NewGuid();
    }

    public DateTime DataDeAniversario { get; set; }
    public string CPF { get; set; }
    public ValidationResult ResultadoValidacao { get; set; }
    public bool IsValid()
    {
        ...

        return ResultadoValidacao.IsValid;
    }
}

class address

public class Endereco : ISelfValidator
{
    public Endereco()
    {
        IdEndereco = Guid.NewGuid();
    }

    public Guid IdEndereco { get; set; }
    public string CodigoCep { get; set; }
    public virtual Cep Cep { get; set; }
    public string Numero { get; set; }
    public string Complemento { get; set; }
    public TipoEndereco TipoEndereco { get; set; }
    public Guid IdPessoa { get; set; }
    public virtual Pessoa Pessoa { get; set; }
    public ValidationResult ResultadoValidacao { get; private set; }
}

client fluent mapping

public class ClienteConfiguration : EntityTypeConfiguration<Cliente>
{
    public ClienteConfiguration()
    {
        Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Clientes");
        });

        Ignore(t => t.ResultadoValidacao);

        Property(x => x.DataDeAniversario)
            .IsRequired();

        Property(x => x.CPF)
                .IsRequired()
                .IsFixedLength()
                .IsUnicode(false)
                .HasColumnType("char")
                .HasMaxLength(11);
    }
}

person fluent mapping

public class PessoaConfiguration : EntityTypeConfiguration<Pessoa>
{
    public PessoaConfiguration()
    {
        HasKey(x => x.IdPessoa);

        Property(x => x.IdPessoa)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasMany(p => p.Enderecos)
                         .WithRequired(e => e.Pessoa)
                         .HasForeignKey(e => e.IdPessoa);
    }
}

mapping address

public class EnderecoConfiguration : EntityTypeConfiguration<Endereco>
{
    public EnderecoConfiguration()
    {
        HasKey(x => x.IdEndereco);

        Property(x => x.IdEndereco)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(x => x.Numero)
            .IsRequired()
            .IsUnicode(false)
            .HasColumnType("varchar")
            .HasMaxLength(5);

        Property(x => x.Complemento)
            .IsRequired()
            .IsUnicode(false)
            .HasColumnType("varchar")
            .HasMaxLength(100);

        Property(x => x.TipoEndereco)
            .IsRequired();

        Property(x => x.CodigoCep)
            .IsRequired()
            .HasMaxLength(8);

        Ignore(x => x.ResultadoValidacao);

        Property(x => x.IdPessoa)
            .IsRequired();
    }
}

context

public class ProjectContext : DbContextBase
{
    public ProjectContext()
        : base("Project")
    {

    }

    public IDbSet<Pessoa> Pessoas { get; set; }
    public IDbSet<Cliente> Clientes { get; set; }
    public IDbSet<Endereco> Enderecos { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Conventions
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        // General Custom Context Properties
        modelBuilder.Properties()
            .Where(p => p.Name == "Id" + p.ReflectedType.Name )
            .Configure(p => p.IsKey());

        modelBuilder.Properties<string>()
            .Configure(p => p.HasColumnType("varchar"));

        modelBuilder.Properties<string>()
            .Configure(p => p.HasMaxLength(100));

        // ModelConfiguration
        modelBuilder.Configurations.Add(new PessoaConfiguration());
        modelBuilder.Configurations.Add(new ClienteConfiguration());
        modelBuilder.Configurations.Add(new EnderecoConfiguration());

        base.OnModelCreating(modelBuilder);
    }
    
asked by anonymous 24.02.2017 / 21:42

1 answer

2

Cliente inherits Pessoa :

public class Cliente: Pessoa, ISelfValidator { ... }

So you can not determine that Cliente is in a Clientes table. A Cliente will be in Pessoas by default convention:

public class ClienteConfiguration : EntityTypeConfiguration<Cliente>
{
    public ClienteConfiguration()
    {
        Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Clientes");
        });

        ...
    }
    ...
}

In its place, I would improve the decoration of attributes and would not use any mapping:

public class Cliente: Pessoa, IValidatableObject // Retire ISelfValidator. A interface não faz parte do ASP.NET MVC.
{
    public Cliente()
    {
        IdPessoa = Guid.NewGuid();
    }

    [Required]
    [DataType(DataType.Date)]
    public DateTime DataDeAniversario { get; set; }

    [StringLength(11)]
    public string CPF { get; set; }

    // Retire isso.
    //public bool IsValid()
    //{
    //    ...
    //
    //    return ResultadoValidacao.IsValid;
    //}

    // Implemente isso no lugar
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // Faça um yield return new ValidationResult() para cada validação que falhar.
    }
}
    
24.02.2017 / 22:20