I have read a lot of posts and some helped me, but I still have a stackoverflow on a one-to-one relation (between Employe and Adresse) defined with Entity framework 6 fluent. The error appears on AdresseDTO when I create a new instance of a ViewModel wich contains some DTOs.
My plain objects
public class Personne
{
public int id { get; set; }
public string civ { get; set; }
public string nom { get; set; }
public string prenom { get; set; }
public string email { get; set; }
public string tel1 { get; set; }
public string tel2 { get; set; }
public Boolean isFournisseur { get; set; }
public Boolean isClient { get; set; }
public Boolean isDeleted { get; set; }
public virtual Adresse adresse { get; set; }
public virtual Utilisateur utilisateur { get; set; }
public Personne()
{
}
}
public class Employe : Personne
{
public virtual TEmploye typeEmploye { get; set; }
public virtual List<AffectationService> affectationServices { get; set; }
public Employe()
{
}
}
public class AffectationService
{
public int id { get; set; }
public virtual Employe employe { get; set; }
public virtual Service service { get; set; }
public virtual Droit groupe { get; set; }
public Boolean isPrincipal { get; set; }
}
public class TEmploye
{
public int id { get; set; }
public string libe { get; set; }
public TEmploye()
{
}
}
public class Adresse
{
public int id { get; set; }
public string numRue { get; set; }
public string nomRue { get; set; }
public string codePostal { get; set; }
public string ville { get; set; }
public string pays { get; set; }
public virtual Personne personne { get; set; }
public Adresse()
{
}
}
My DTOs
public class PersonneDTO
{
public int id { get; set; }
public bool isDeleted { get; set; }
public string civ { get; set; }
public string nom { get; set; }
public string prenom { get; set; }
public string email { get; set; }
public string tel1 { get; set; }
public string tel2 { get; set; }
public AdresseDTO adresse { get; set; }
public UtilisateurDTO utilisateur { get; set; }
public PersonneDTO()
{
adresse = new AdresseDTO();
utilisateur = new UtilisateurDTO();
}
}
public class EmployeDTO : PersonneDTO
{
public virtual TEmployeDTO typeEmploye { get; set; }
public virtual List<AffectationServiceDTO> affectationServices { get; set; }
public EmployeDTO()
{
affectationServices = new List<AffectationServiceDTO>();
typeEmploye = new TEmployeDTO();
}
}
public class TEmployeDTO
{
public int id { get; set; }
public string libe { get; set; }
public TEmployeDTO()
{
}
}
public class AffectationServiceDTO
{
public int id { get; set; }
public virtual EmployeDTO employe { get; set; }
public virtual ServiceDTO service { get; set; }
public virtual DroitDTO groupe { get; set; }
public Boolean isPrincipal { get; set; }
public AffectationServiceDTO()
{
service = new ServiceDTO();
groupe = new DroitDTO();
employe = new EmployeDTO();
}
}
public class AdresseDTO
{
public int id { get; set; }
public string numRue { get; set; }
public string nomRue { get; set; }
public string codePostal { get; set; }
public string ville { get; set; }
public string pays { get; set; }
public AdresseDTO()
{
}
}
How I mapp my DTOs with the plain objects
//DomainToViewModel
CreateMap<Adresse, AdresseDTO>().MaxDepth(1);
CreateMap<Personne, PersonneDTO>().MaxDepth(1);
CreateMap<Employe, EmployeDTO>().MaxDepth(1);
CreateMap<AffectationService, AffectationServiceDTO>().MaxDepth(1);
CreateMap<TEmploye, TEmployeDTO>().MaxDepth(1);
//ViewModelToDomain
CreateMap<AdresseDTO, Adresse>().MaxDepth(1)
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.codePostal, map => map.MapFrom(vm => vm.codePostal))
.ForMember(g => g.nomRue, map => map.MapFrom(vm => vm.nomRue))
.ForMember(g => g.numRue, map => map.MapFrom(vm => vm.numRue))
.ForMember(g => g.pays, map => map.MapFrom(vm => vm.pays))
.ForMember(g => g.ville, map => map.MapFrom(vm => vm.ville));
CreateMap<UtilisateurDTO, Utilisateur>().MaxDepth(1)
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.dConnexion, map => map.MapFrom(vm => vm.dConnexion))
.ForMember(g => g.dCreation, map => map.MapFrom(vm => vm.dCreation))
.ForMember(g => g.isActive, map => map.MapFrom(vm => vm.isActive))
.ForMember(g => g.isDeleted, map => map.MapFrom(vm => vm.isDeleted))
.ForMember(g => g.login, map => map.MapFrom(vm => vm.login))
.ForMember(g => g.password, map => map.MapFrom(vm => vm.password))
.ForMember(g => g.personne, map => map.MapFrom(vm => vm.personne)).MaxDepth(1);
CreateMap<EmployeDTO, Employe>().MaxDepth(1)
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.typeEmploye, map => map.MapFrom(vm => vm.typeEmploye))
.ForMember(g => g.affectationServices, map => map.MapFrom(vm => vm.affectationServices))
.ForMember(g => g.utilisateur, map => map.MapFrom(vm => vm.utilisateur)).MaxDepth(1)
.ForMember(g => g.adresse, map => map.MapFrom(vm => vm.adresse)).MaxDepth(1);
CreateMap<TEmployeDTO, TEmploye>().MaxDepth(1)
.ForMember(g => g.libe, map => map.MapFrom(vm => vm.libe));
CreateMap<AffectationServiceDTO, AffectationService>().MaxDepth(1)
.ForMember(g => g.id, map => map.MapFrom(vm => vm.id))
.ForMember(g => g.employe, map => map.MapFrom(vm => vm.employe)).MaxDepth(1)
.ForMember(g => g.groupe, map => map.MapFrom(vm => vm.groupe)).MaxDepth(1)
.ForMember(g => g.isPrincipal, map => map.MapFrom(vm => vm.isPrincipal))
.ForMember(g => g.service, map => map.MapFrom(vm => vm.service)).MaxDepth(1);
Mapping with EF6 fluent
public PersonneConfiguration()
{
ToTable("Personne");
HasKey<int>(a => a.id);
HasRequired<Adresse>(x => x.adresse);
HasOptional<Utilisateur>(x => x.utilisateur);
Property(a => a.civ).HasColumnType("varchar").HasMaxLength(3);
Property(a => a.nom).HasColumnType("varchar").HasMaxLength(80);
Property(a => a.prenom).HasColumnType("varchar").HasMaxLength(80);
Property(a => a.email).HasColumnType("varchar").HasMaxLength(150);
Property(a => a.tel1).HasColumnType("varchar").HasMaxLength(10);
Property(a => a.tel2).HasColumnType("varchar").HasMaxLength(10);
Property<bool>(a => a.isClient);
Property<bool>(a => a.isFournisseur);
Property<bool>(a => a.isDeleted);
}
public EmployeConfiguration()
{
ToTable("Employe");
HasKey<int>(a => a.id);
HasOptional<TEmploye>(x => x.typeEmploye);
Property<bool>(a => a.isDeleted);
}
public AdresseConfiguration()
{
ToTable("Adresse");
HasKey<int>(a => a.id);
Property(a => a.codePostal).HasColumnType("varchar").HasMaxLength(5);
Property(a => a.nomRue).HasColumnType("varchar").HasMaxLength(150);
Property(a => a.numRue).HasColumnType("varchar").HasMaxLength(10);
Property(a => a.ville).HasColumnType("varchar").HasMaxLength(80);
Property(a => a.pays).HasColumnType("varchar").HasMaxLength(80);
}
public AffectationServiceConfiguration()
{
ToTable("AffectationService");
HasKey<int>(a => a.id);
HasRequired<Employe>(x => x.employe).WithMany(x => x.affectationServices);
HasRequired<Service>(x => x.service);
HasRequired<Droit>(x => x.groupe);
Property<bool>(a => a.isPrincipal);
}
public TEmployeConfiguration()
{
ToTable("TEmploye");
HasKey<int>(a => a.id);
Property(a => a.libe).HasColumnType("varchar").HasMaxLength(100);
}
And the ViewModel taht causes the error
public class EditEmployeViewModel
{
public EmployeDTO personne { get; set; }
public EditEmployeViewModel()
{
personne = new EmployeDTO();
}
}
The stackoverflow occurs when a create a new EmployeDTO(). I tried to solve this by adding .MaxDepth(1) where it's possible, but it doesn't work... Sorry guys, I know that is a long post, but I don't have any idea about my problem so I try to show you the most relevent part of my code.
Thank you for all, I'm brand new in EF6 so if you have any tips or good pratices to share it will be a pleasure.
thank you for your help. I didnt' find a real solution so I removed the refererence Personne in my object Adresse to avoid the stackoverflow exception...