Hi,
I have a many to many relation entity for Person and Tache (task in English) but the Persons data in not displayed when calling the task entity ?
Person Entity : ...... public List<Tache> Taches { get; set; }
Tache Entity
public List<Person> Persons { get; set; }
Request :
var dbList = _tacheRepository.GetAllIncluding(x => x.Persons).Where(x => x.Id == tache.Id); var dbList2 = _tacheRepository.GetAll().Include(x => x.Persons).Where(x => x.Id == tache.Id);
the model creating
` modelBuilder.Entity
modelBuilder.Entity<Tache>()
.HasMany(e => e.Persons)
.WithMany(e => e.Taches)
.UsingEntity("PersonTache");
`
database
Any idea ?
Thks
17 Answer(s)
-
0
Hi @Bernard,
You need to execute a method to load related entities.
For example:
var dbList = _tacheRepository.GetAllIncluding(x => x.Persons).Where(x => x.Id == tache.Id).ToList();
orvar dbList = _tacheRepository.GetAllIncluding(x => x.Persons).FirstOrDefault(x => x.Id == tache.Id);
-
0
Hi
Thks for quick answer If you look above it is the same code as you
var dbList = _tacheRepository.GetAllIncluding(x => x.Persons).Where(x => x.Id == tache.Id);
But no data is returned for person entity
-
0
Hi @Bernard,
Could you add
ToList()
to the end of your code? I think it will solve the problem. -
0
Hi @m.aliozkaya,
For the 2 cases the results are 0
And same result for searching Tasks (tache in french) in personappservice :
var dbListPerson = _personRepository.GetAllIncluding(x => x.Taches).Where(x => x.Id == input.Id).ToList(); var dbListPerson2 = _personRepository.GetAllIncluding(x => x.Taches).FirstOrDefault(x => x.Id == input.Id);
-
0
Hi Bernard
Have you tried listing without conditions? Does it still give the same result?
-
0
-
0
Hi Bernard
When using Include here, there is no need for Id synchronization, it does this automatically. Here, there are 2 Persons objects in the entity with ID 2.
Entity Framework uses dynamic proxies to support features such as lazy loading. These proxies typically use the ICollection implementation, and concrete types such as List may be incompatible with these proxies.
The ICollection interface keeps your code consistent when working with collections
ICollection represents an interface to a collection, which allows you to write more flexible code rather than a concrete implementation like List
-
0
Thks for explanation
So, I have a stupid question how to add a task to the person entity without having a PersonTache entity in the dbcontext. The table was created by itself in the database
This way (mapping from multiselect field and) ?
public class CreateOrEditTacheDto : EntityDto<int?> {
[Required] [StringLength(TacheConsts.MaxIntituleLength, MinimumLength = TacheConsts.MinIntituleLength)] public string Intitule { get; set; } public DateTime Echeance { get; set; } public Priorite Priorite { get; set; } public TypeTache TypeTache { get; set; } public long UserId { get; set; } public List<PersonDto> Persons { get; set; }
}
-
0
Hi Bernard
You can correct the structure you applied in the OnModelCreating method according to your wishes. This is what you did before
modelBuilder.Entity() .HasMany(e => e.Taches) .WithMany(e => e.Persons) .UsingEntity("PersonTache"); modelBuilder.Entity() .HasMany(e => e.Persons) .WithMany(e => e.Taches) .UsingEntity("PersonTache");
If you want to establish a One to Many relationship here, 2 definitions are not needed.
You can also do this in Entity classes, you can make more specific definitions in OnModelCreating.
The current definition you made in OnModelCreating creates a Many-to-Many relationship. This automatically creates the PersonTache entity.
-
0
Thks a lot for this reply
-
0
Hi
Sorry for re-opening this subject but i have issue when trying to save entity :
` public virtual async Task CreateOrEdit(CreateOrEditTacheDto input) { if (input.Id == null) { await Create(input); } else { var taskForperson1 = new PersonTacheDto(); var taskForperson2 = new PersonTacheDto();
taskForperson1.Id = 16; taskForperson2.Id = 17; taskForperson1.TacheId = 4; taskForperson2.TacheId = 4; input.Persons.Add(taskForperson1); input.Persons.Add(taskForperson2); await Update(input); }
}`
Automapper issue
AutoMapper.AutoMapperMappingException: Error mapping types.
Mapping types: CreateOrEditTacheDto -> Tache ERUDY.Commercial.Dtos.CreateOrEditTacheDto -> ERUDY.Commercial.Tache
Type Map configuration: CreateOrEditTacheDto -> Tache ERUDY.Commercial.Dtos.CreateOrEditTacheDto -> ERUDY.Commercial.Tache
Destination Member: Persons
---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types: PersonTacheDto -> Person ERUDY.Commercial.Dtos.PersonTacheDto -> ERUDY.Commercial.Person at lambda_method4386(Closure, PersonTacheDto, Person, ResolutionContext) at lambda_method4385(Closure, CreateOrEditTacheDto, Tache, ResolutionContext) --- End of inner exception stack trace --- at lambda_method4385(Closure, CreateOrEditTacheDto, Tache, ResolutionContext) at Abp.AutoMapper.AutoMapperObjectMapper.Map[TSource,TDestination](TSource source, TDestination destination) at ERUDY.Commercial.TachesAppService.Update(CreateOrEditTacheDto input) in C:\Users\Bernard\source\repos\Erudy\src\ERUDY.Application\Commercial\TachesAppService.cs:line 185 at Abp.Authorization.AuthorizationInterceptor.InternalInterceptAsynchronous(IInvocation invocation) at ERUDY.Commercial.TachesAppService.CreateOrEdit(CreateOrEditTacheDto input) in C:\Users\Bernard\source\repos\Erudy\src\ERUDY.Application\Commercial\TachesAppService.cs:line 163 at Abp.Authorization.AuthorizationInterceptor.InternalInterceptAsynchronous(IInvocation invocation) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker....
-
0
Hi Bernard
You need to define the [AutoMapFrom(typeof(Tache))] attribute in the CreateOrEditTacheDto class, and similarly, define the [AutoMapFrom(typeof(Person))] attribute in the PersonTacheDto class. A comprehensive explanation is provided in this document.
-
0
-
0
Hi Bernard
Make sure that the
Abp.AutoMapper
package is installed in the project in which you want to use the AutoMapFrom attribute. -
0
-
0
Hi,
I'm moving forward with my problem, I changed the initial request :
var person = await _personRepository.FirstOrDefaultAsync(input.Id);
by
var person = await _personRepository.GetAllIncluding(x => x.Taches).FirstOrDefaultAsync(x => x.Id == input.Id);
this gives me an include collection of taches :
But the mapping doesn't work :
For reminding GetPersonForEditOutput class looks like :
` public class GetPersonForEditOutput { public CreateOrEditPersonDto Person { get; set; }
public virtual Guid? PictureId { get; set; } public string TacheIntitule { get; set; } public string PersonIntitule { get; set; } public string EntityFullName { get; set; } public List<string> AllEntities { get; set; } public List<DynamicPropertyDto> DynamicProperties { get; set; } public ICollection<TacheDto> Taches { get; set; }
}`
and ( i does not add public ICollection<TacheDto> Taches { get; set; } in it)
` public class CreateOrEditPersonDto : EntityDto<int?> {
[StringLength(PersonConsts.MaxIntituleLength, MinimumLength = PersonConsts.MinIntituleLength)] public string Intitule { get; set; } [StringLength(PersonConsts.MaxAdresse1Length, MinimumLength = PersonConsts.MinAdresse1Length)] public string Adresse1 { get; set; } [StringLength(PersonConsts.MaxAdresse2Length, MinimumLength = PersonConsts.MinAdresse2Length)] public string Adresse2 { get; set; } [StringLength(PersonConsts.MaxAdresse3Length, MinimumLength = PersonConsts.MinAdresse3Length)] public string Adresse3 { get; set; } [StringLength(PersonConsts.MaxCodePostalLength, MinimumLength = PersonConsts.MinCodePostalLength)] public string CodePostal { get; set; } [StringLength(PersonConsts.MaxVilleLength, MinimumLength = PersonConsts.MinVilleLength)] public string Ville { get; set; } [StringLength(PersonConsts.MaxEmailLength, MinimumLength = PersonConsts.MinEmailLength)] public string Email { get; set; } [StringLength(PersonConsts.MaxTelLength, MinimumLength = PersonConsts.MinTelLength)] public string Telephone { get; set; } [StringLength(PersonConsts.MaxNotesLength, MinimumLength = PersonConsts.MinNotesLength)] public string Notes { get; set; } public TypePerson TypePerson { get; set; } [StringLength(PersonConsts.MaxCodeClientLength, MinimumLength = PersonConsts.MinCodeClientLength)] public string CodeClient { get; set; } [StringLength(PersonConsts.MaxCodeComptableLength, MinimumLength = PersonConsts.MinCodeComptableLength)] public string CodeComptable { get; set; } public Guid? PictureId { get; set; } public bool IsActive { get; set; } [StringLength(PersonConsts.MaxNomJeuneFilleLength, MinimumLength = PersonConsts.MinNomJeuneFilleLength)] public string NomJeuneFille { get; set; } public DateTime? DateNaissance { get; set; } public string Nationalite { get; set; } [StringLength(PersonConsts.MaxNumSecuLength, MinimumLength = PersonConsts.MinNumSecuLength)] public string NumSecu { get; set; } [StringLength(PersonConsts.MaxPrenomLength, MinimumLength = PersonConsts.MinPrenomLength)] public string Prenom { get; set; } [StringLength(PersonConsts.MaxNomLength, MinimumLength = PersonConsts.MinNomLength)] public string Nom { get; set; } [StringLength(PersonConsts.MaxFonctionLength, MinimumLength = PersonConsts.MinFonctionLength)] public string Fonction { get; set; } public string CodeNaf { get; set; } public string Siret { get; set; } [StringLength(PersonConsts.MaxFormeJuridiqueLength, MinimumLength = PersonConsts.MinFormeJuridiqueLength)] public string FormeJuridique { get; set; } [Range(PersonConsts.MinEmployesValue, PersonConsts.MaxEmployesValue)] public int Employes { get; set; } public decimal CA { get; set; } public string Adeli { get; set; } public string RPPS { get; set; } public ListSource Source { get; set; } public ListeProfilMorale ProfilMorale { get; set; } public ListeProfilPhysique ProfilPhysique { get; set; } public ListeCivilite Civilite { get; set; } public ListeProfilIntervenant ProfilIntervenant { get; set; } public TypeStagiaire TypeStagiaire { get; set; } public ListeStatutPerson Statut { get; set; } public int? ParentId { get; set; }`
and Person class entity :
[Table("Persons")] public class Person : Entity, IMayHaveTenant,ISoftDelete { ............. public ICollection<Tache> Taches { get; set; }
}
-
0
Hi oguzhanagir,
I found the solution :
public ICollection<Tache> Taches { get; set; } was in the wrong class : Should be in CreateOrEditPersonDto anf not in GetPersonForEditOutput !
Thks anyway for your precious help
bernard