Error in running update-database Migration

Asked

Viewed 366 times

1

I am trying to run the creation of my database, but I am getting this error below and am not understanding the reason:

The type 'Client' cannot 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 so as not to map inherited properties, or change all types in the Hierarchy to map inherited properties and to 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; }
}

Customer 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;
    }
}

address class

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; }
}

customer 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);
    }
}

mapping Fluent person

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);
    }
}

address mapping

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);
    }

1 answer

2


Cliente inherits Pessoa:

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

So you can’t determine that Cliente is in a table Clientes. A Cliente will stay in the Pessoas by standard 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.
    }
}
  • then @gypsy-Morrison-I need the base to be created in a Table by Type Concrete pattern where each entity has its table separately and person is just a class that normalizes certain fields I had already managed to do something so I just don’t understand why it’s not working anymore

  • So it’s not inheritance. It’s composition. See here.

  • I understand what you demonstrated there, I even did so, but I do not want to compose, I do not want the table person nor exist, I just want to exist as the entity, customer and supplier .... person just offers me her attributes so that I don’t keep repeating over and over again the same data, and in the address table I would only have idPeople like this, would not matter who is the entity that is persisting ... only the id that would be similar to everyone and best of all would not have to put a field like

  • So you map Pessoa as abstract and does not create neither content, nor configuration for it. You will get where you need.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.