Base solution for your next web application
Open Closed

Including Method #12106


User avatar
0
Bernard created

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)
  • User Avatar
    0
    m.aliozkaya created
    Support Team

    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(); or var dbList = _tacheRepository.GetAllIncluding(x => x.Persons).FirstOrDefault(x => x.Id == tache.Id);

  • User Avatar
    0
    Bernard created

    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

  • User Avatar
    0
    m.aliozkaya created
    Support Team

    Hi @Bernard,

    Could you add ToList() to the end of your code? I think it will solve the problem.

  • User Avatar
    0
    Bernard created

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

  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi Bernard

    Have you tried listing without conditions? Does it still give the same result?

  • User Avatar
    0
    Bernard created

    Well seen **oguzhanagir **!

    But don't understand the id is the same (2)

    i understand the problem is ICollection instead of List in each Entity

  • User Avatar
    0
    oguzhanagir created
    Support Team

    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

  • User Avatar
    0
    Bernard created

    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&lt;PersonDto&gt; Persons { get; set; }
    

    }

  • User Avatar
    0
    oguzhanagir created
    Support Team

    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.

  • User Avatar
    0
    Bernard created

    Thks a lot for this reply

  • User Avatar
    0
    Bernard created

    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....

  • User Avatar
    0
    oguzhanagir created
    Support Team

    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.

  • User Avatar
    0
    Bernard created

    Hi

    In both case Automap doesn't exist ans installing failed

  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi Bernard

    Make sure that the Abp.AutoMapper package is installed in the project in which you want to use the AutoMapFrom attribute.

  • User Avatar
    0
    Bernard created

    The ABP-Automapper is installed

    But still issue

  • User Avatar
    0
    Bernard created

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

    }

  • User Avatar
    0
    Bernard created

    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