Relationship error with Entity Framework

1

I'm developing a test project that I want to include in my TCC, but I encountered a problem matching two entities to create the tables in the database with the Entity Framework. They are 'Post' and 'Comment'

   public class Post
    {
        public Post()
        {
            DataPost = DateTime.Now;
            Categoria = new Categoria();
            Comentarios = new List<Comentario>();
        }

        public int PostId { get; set; }

        public string TituloPost { get; set; }

        public string SubTituloPost { get; set; }

        public DateTime DataPost { get; set; }

        //Post obrigatoriamente tem uma categoria
        public virtual Categoria Categoria { get; set; }

        //Post tem 0 ou vários comentários
        public virtual ICollection<Comentario> Comentarios { get; set; } //=====Comentários

        public override string ToString()
        {
            return TituloPost;
        }
    }

Comment class

    public class Comentario
    {
        public Comentario()
        {
            DataComentario = DateTime.Now;
            Post = new Post();
        }

        public int ComentarioId { get; set; }

        public DateTime DataComentario { get; set; }

        public string DescricaoComentario { get; set; }

        //1 Cometário pertence somente a 1 Post
        public virtual Post Post { get; set; } //=============Post

        public override string ToString()
        {
            return DescricaoComentario;
        }
    }

Category class

public class Categoria
{
    public Categoria()
    {
        Ativa = true;
        Posts = new List<Post>();
    }

    public int CategoriaId { get; set; }

    public string DescricaoCategoria { get; set; }

    public bool Ativa { get; set; }

    //Categoria tem uma coleção de Post
    public virtual ICollection<Post> Posts { get; set; }

    public override string ToString()
    {
        return DescricaoCategoria;
    }

}

I tried to do the mapping in several ways as presented in this post ..: link Part 2.

But in all ways I've tried it, it creates the tables the way I need it, and I can even insert the Post, but when I insert a comment it gives a relationship error.

Who can help me, I thank you.

Edit

MAPPING

public class MapPost : EntityTypeConfiguration<Post>
{
    public MapPost()
    {
        ToTable("Post");
        HasKey(x => x.PostId);
        Property(x => x.TituloPost).HasMaxLength(150).IsRequired();
        Property(x => x.SubTituloPost).HasMaxLength(300).IsRequired();
        Property(x => x.DataPost).IsRequired();

        HasRequired(p => p.Categoria)
            .WithMany(c => c.Posts)
            .Map(c => c.MapKey("CategoriaId"));
    }
}


public class MapCategoria : EntityTypeConfiguration<Categoria>
{
    public MapCategoria()
    {
        ToTable("Categoria");
        HasKey(i => i.CategoriaId);
        Property(d => d.DescricaoCategoria).HasMaxLength(60).IsRequired();
    }
}



public class MapComentario : EntityTypeConfiguration<Comentario>
{
    public MapComentario()
    {
        ToTable("Comentario");
        HasKey(i => i.ComentarioId);
        Property(d => d.DataComentario).IsRequired();
        Property(d => d.DescricaoComentario).IsRequired();

        HasRequired(x => x.Post)
            .WithMany(c => c.Comentarios)
            .Map(x => x.MapKey("fk_PostId"));
    }
}

CONTEXT

public class Context : DbContext
{
    public Context() : base ("ConnectionString")
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }

    public DbSet<Categoria> Categoria { get; set; }

    public DbSet<Post> Post { get; set; }

    public DbSet<Comentario> Comentario { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        modelBuilder.Properties<string>().Configure(p => p.HasColumnType("varchar"));

        modelBuilder.Configurations.Add(new Map.MapPost());
        modelBuilder.Configurations.Add(new Map.MapCategoria());
        modelBuilder.Configurations.Add(new Map.MapComentario());

        base.OnModelCreating(modelBuilder);
    }
}

INSERTING DATA

        var post = new Post
        {
             TituloPost = "Titulo Post 02",
             SubTituloPost = "SubTitulo Post 02",
             Categoria = new Categoria
             {
                   DescricaoCategoria = "Categoria de Teste 02",
                   Ativa = true,
             },
             Comentarios = new List<Comentario>
             {
                 new Comentario
                 {
                     DescricaoComentario = "Comentário Teste 01",
                     DataComentario = DateTime.Now
                 },

                 new Comentario
                 {
                     DescricaoComentario = "Comentário Teste 02",
                     DataComentario = DateTime.Now
                 },

                 new Comentario
                 {
                     DescricaoComentario = "Comentário Teste 03",
                     DataComentario = DateTime.Now
                 }
             }
        };
        db.Post.Add(post);
        if (!db.GetValidationErrors().Any())
        {
            db.SaveChanges();
        }

ERROR

OBERVAÇÃO

The database I'm using is MySql.

    
asked by anonymous 11.07.2017 / 04:43

1 answer

0

Friend, see if this helps you, as this code below as soon as you perform the migration to the database the tables will be created as follows.

  

Classes

publicclassPais{publicPais(){Estados=newList<Estado>();}publicintHandle{get;set;}publicstringNome{get;set;}publicstringSigla{get;set;}publicIEnumerable<Estado>Estados{get;set;}}publicclassEstado:EntityBase{publicEstado(){Cidades=newList<Cidade>();}publicintHandle{get;set;}publicstringNome{get;set;}publicstringSigla{get;set;}publiclongPaisHandle{get;set;}publicPaisPais{get;set;}publicIEnumerable<Cidade>Cidades{get;set;}}publicclassCidade{publicCidade(){}publicintHandle{get;set;}publicstringNome{get;set;}publicstringSigla{get;set;}publiclongEstadoHandle{get;set;}publicEstadoEstado{get;set;}}
  

MappingEntities

publicclassPaisMap:EntityTypeConfiguration<Pais>{publicPaisMap(){ToTable("PAIS");

        HasKey(x => x.Handle);

        Property(x => x.Handle)
            .HasColumnName("HANDLE")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);

        Property(x => x.Nome)
            .IsRequired()
            .HasMaxLength(150)
            .HasColumnName("NOME");

        Property(x => x.Sigla)
            .IsRequired()
            .HasMaxLength(3)
            .HasColumnName("SIGLA");                              
    }

}

public class EstadoMap : EntityTypeConfiguration<Estado>
{
    public EstadoMap()
    {
        ToTable("ESTADO");

        HasKey(x => x.Handle);

        Property(x => x.Handle)
            .HasColumnName("HANDLE")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);

        Property(x => x.Nome)
            .IsRequired()
            .HasMaxLength(150)
            .HasColumnName("NOME");

        Property(x => x.Sigla)
            .IsRequired()
            .HasMaxLength(2)
            .HasColumnName("SIGLA");

        HasRequired(x => x.Pais)
            .WithMany()
            .HasForeignKey(x => x.PaisHandle);

        Property(x => x.PaisHandle)
            .HasColumnName("PAISHANDLE");
    }
}

public class CidadeMap : EntityTypeConfiguration<Cidade>
{
    public CidadeMap()
    {
        ToTable("CIDADE");

        HasKey(x => x.Handle);

        Property(x => x.Handle)
            .HasColumnName("HANDLE")
            .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);

        Property(x => x.Nome)
            .IsRequired()
            .HasMaxLength(150)
            .HasColumnName("NOME");

        Property(x => x.Sigla)
            .IsRequired()
            .HasMaxLength(3)
            .HasColumnName("SIGLA");

        HasRequired(x => x.Estado)
            .WithMany()
            .HasForeignKey(x => x.EstadoHandle);

        Property(x => x.EstadoHandle)
            .HasColumnName("ESTADOHANDLE");
    }
}
  

Context class

public class DataContext : DbContext
{
    public DataContext() : base("name=DefaultConnection")
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }

    public DbSet<Pais> Pais { get; set; }
    public DbSet<Estado> Estado { get; set; }
    public DbSet<Cidade> Cidade { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Aqui vamos remover a pluralização padrão do Etity Framework que é em inglês
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        /*Desabilitamos o delete em cascata em relacionamentos 1:N evitando
         ter registros filhos     sem registros pai*/
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

        //Basicamente a mesma configuração, porém em relacionamenos N:N
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        /*Toda propriedade do tipo string na entidade POCO
         seja configurado como VARCHAR no SQL Server*/

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

        modelBuilder.Configurations.Add(new PaisMap());
        modelBuilder.Configurations.Add(new EstadoMap());
        modelBuilder.Configurations.Add(new CidadeMap());            

        base.OnModelCreating(modelBuilder);
    }
}
    
11.07.2017 / 11:22