Mapping relationships with Fluent API
I have three simple classes of city, state and country. I realized that simply declaring a property of type Estado
in class Cidade
the foreign key is generated correctly. I would like to know how to do these mappings in hand, I get safer, and if my concern is for nothing, there is doubt about the need to have the options to map in hand.
Entities follow:
public class CidadeEntity {
public int Id { get; set; }
public string Nome { get; set; }
//public int EstadoId { get; set; }
public virtual EstadoEntity Estado { get; set; }
}
public class EstadoEntity{
public int Id { get; set; }
public string Sigla { get; set; }
public string Nome { get; set; }
public virtual IList<CidadeEntity> CidadeLista { get; set; }
//public byte EstadoPaisId { get; set; }
public virtual PaisEntity Pais { get; set; }
}
public class PaisEntity {
public int Id { get; set; }
public string Sigla { get; set; }
public string Nome { get; set; }
public virtual IList<EstadoEntity> EstadoLista { get; set; }
}
My mappings:
public CidadeMap() {
ToTable("Cidade");
HasKey(c => c.Id);
Property(p => p.Nome)
.IsRequired()
.HasColumnType("varchar")
.HasMaxLength(120);
//HasRequired(f => f.Estado).WithMany(p => p.CidadeLista).HasForeignKey(p => p.EstadoId);
}
public EstadoMap() {
ToTable("Estado");
HasKey(c => c.Id);
Property(p => p.Sigla).IsRequired().HasColumnType("char").HasMaxLength(5);
Property(p => p.Nome).IsRequired().HasColumnType("varchar").HasMaxLength(75);
//Ignore(p => p.EstadoPaisId);
//Relacionamentos
HasRequired(p => p.CidadeLista).WithRequiredPrincipal().Map(p => p.MapKey("EstadoId"));
}
public PaisMap() {
ToTable("Pais");
HasKey(c => c.Id);
Property(p => p.Sigla)
.HasColumnType("varchar")
.HasMaxLength(5);
Property(p => p.Nome)
.HasColumnType("varchar")
.HasMaxLength(50);
}
Context with BD:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class DataContext:DbContext {
public DataContext():base("ConexaoBD") {
}
public DbSet<PaisEntity> Pais { get; set; }
public DbSet<EstadoEntity> Estado { get; set; }
public DbSet<CidadeEntity> Cidade { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Configurations.Add(new PaisMap());
modelBuilder.Configurations.Add(new EstadoMap());
modelBuilder.Configurations.Add(new CidadeMap());
base.OnModelCreating(modelBuilder);
}
}
In EstadoMap
I did the mapping with Cidade
(HasRequired(p => p.CidadeLista).WithRequiredPrincipal().Map(p => p.MapKey("EstadoId"))
) but it was duplicated because it generated mine and the automatic mapping (this without nullable: false
), I saw that you can do this mapping by the city also (HasRequired(p => p.Estado).WithRequiredDependent();
), but it did not work and I did not realize if there is a difference from the state to the city and vice versa. I don't know if I'm doing things right.
1 answers
So I made some adaptations mainly in your classes:
CityMAP
Keep
HasRequired(a => a.Estado).WithMany(a => a.CidadeLista).HasForeignKey(a => a.EstadoId);
Statemap
HasRequired(p => p.CidadeLista).WithRequiredPrincipal().Map(p => p.MapKey("EstadoId"));
Changed to
HasRequired(a => a.Pais).WithMany(a => a.EstadoLista).HasForeignKey(a => a.PaisId);
Cityentity
I added
public int EstadoId { get; set; }
Statusentity
I added
public int PaisId { get; set; }
My context looked like this
public class ExemploContext : DbContext
{
public ExemploContext()
:base("DefaultConnection")
{
}
public DbSet<EstadoEntity> Estados { get; set; }
public DbSet<CidadeEntity> Cidades { get; set; }
public DbSet<PaisEntity> Paises { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new EstadoMap());
modelBuilder.Configurations.Add(new CidadeMap());
modelBuilder.Configurations.Add(new PaisMap());
base.OnModelCreating(modelBuilder);
}
}
The source code of the example you can take Here
I'm not very good with concepts, but in practice the example I gave is how I usually work with relationship mapping in EntityFramework using Fluent API