1

The GetAll and Get methods of the ready-made CrudAppService don't include child entities.

Is it possible to modify its behaviour?

Update

GetAllIncluding has some problem if the included entity has a navigation property to the parent; it falls into a sort of circular dependency. Is there any Attribute or trick to exclude the navigation property from the serialization? The [NonSerialized] attribute does not seem to be applicable to a navigation property.

PostAppService:

public class PostAppService : CrudAppService<Post, PostDto>, IPostAppService
{
    IRepository<Post> _repository = null;

    public PostAppService(IRepository<Post> repository) : base(repository)
    {
        _repository = repository;
    }

    protected override IQueryable<Post> CreateFilteredQuery(PagedAndSortedResultRequestDto input)
    {
        return _repository.GetAllIncluding(p => p.Items);
    }
}

PostDto:

[AutoMap(typeof(Post))]
public class PostDto : EntityDto
{
    public ICollection<Item> Items { get; set; }
}

Post entity:

[Table("AbpPosts")]
public class Post : FullAuditedEntity<int,User>
{
    public virtual ICollection<Item> Items { get; set; }
}

Item entity:

[Table("AbpItems")]
public class Item : Entity
{
    [ForeignKey("PostId")]
    public Post Post { get; set; }
    public int PostId { get; set; }
}
aaron
  • 39,695
  • 6
  • 46
  • 102
pinale
  • 2,060
  • 6
  • 38
  • 72

5 Answers5

8

You have to use eager-loading.

Override CreateFilteredQuery and GetEntityById in your AppService:

public class MyAppService : CrudAppService<ParentEntity, ParentEntityDto>, IMyAppService
{
    public MyAppService(IRepository<ParentEntity> repository)
        : base(repository)
    {
    }

    protected override IQueryable<ParentEntity> CreateFilteredQuery(PagedAndSortedResultRequestDto input)
    {
        return Repository.GetAllIncluding(p => p.ChildEntity);
    }

    protected override ParentEntity GetEntityById(int id)
    {
        var entity = Repository.GetAllIncluding(p => p.ChildEntity).FirstOrDefault(p => p.Id == id);
        if (entity == null)
        {
            throw new EntityNotFoundException(typeof(ParentEntity), id);
        }

        return entity;
    }
}

The benefit of overriding these methods is that you continue to get permission checking, counting, sorting, paging and mapping for free.

Update

GetAllIncluding has some problem if the included entity has a navigation property to the parent; it falls into a sort of circular dependency. Is there any Attribute or trick to exclude the navigation property from the serialization?

Return ItemDto (without navigation property) in PostDto.

aaron
  • 39,695
  • 6
  • 46
  • 102
2

Yes, You have to include explicitly like this.

GetAll().Include(i => i.ChildEntities)
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
1

You have to include the child entities manually. It's lazy loading by design.

Alper Ebicoglu
  • 8,884
  • 1
  • 49
  • 55
  • do you mean create a method (e.g. myGet) that use directly the repository invoking entityframwork include comand? `var events = await _eventRepository .GetAll() .Include(e => e.Registrations) .WhereIf(!input.IncludeCanceledEvents, e => !e.IsCancelled) .OrderByDescending(e => e.CreationTime) .ToListAsync();` – pinale Jan 23 '18 at 14:11
  • yeah @alex . that's exactly what I mean – Alper Ebicoglu Jan 23 '18 at 14:14
  • I did not get why both async and non-async version of CrudService exists. It also confuses me, that non-async versions method are called -Async, deal with Task - so they are kind of "async-ready". So when I am supposed to use one and when another? @vivek-nuna could you please also advice? – Alexander May 29 '20 at 14:21
0

For whom that work with AsyncCrudAppService and you have two different lists of child:

Below to get specific parent Object with their list of child

 protected override Task<Parent> GetEntityByIdAsync(int id)
        {
            var entity = Repository.GetAllIncluding(p => p.listOfFirstChild).Include(x => x.listOfSecondChild).FirstOrDefault(p => p.Id == id);
            return base.GetEntityByIdAsync(id);
        }

Abdulaziz
  • 654
  • 3
  • 12
  • 37
0

In Abp.io All You Need Is (that must be added to PostService inherited from CrudAppService ):

 protected override IQueryable<Post> CreateFilteredQuery(PagedAndSortedResultRequestDto input)
        {
            return _postReposiory
                 .Include(p => p.Item);
        }

smbanaei
  • 1,123
  • 8
  • 14