Получить дочерние объекты из CrudAppService в ABP

GetAll а также Get методы готового CrudAppService не включайте дочерние объекты.

Можно ли изменить его поведение?

Обновить

GetAllIncluding имеет некоторые проблемы, если включенный объект имеет свойство навигации к родителю; это попадает в своего рода круговую зависимость. Есть ли Attribute или трюк, чтобы исключить свойство навигации из сериализации? [NonSerialized] Атрибут не подходит для свойства навигации.

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

Почтовый объект:

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

Элемент объекта:

[Table("AbpItems")]
public class Item : Entity
{
    [ForeignKey("PostId")]
    public Post Post { get; set; }
    public int PostId { get; set; }
}

3 ответа

Решение

Вы должны использовать eager-loading.

Override CreateFilteredQuery а также GetEntityById в вашем 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;
    }
}

Преимущество переопределения этих методов заключается в том, что вы по-прежнему получаете бесплатную проверку, подсчет, сортировку, разбиение по страницам и отображение разрешений.

Обновить

GetAllIncluding имеет некоторые проблемы, если включенный объект имеет свойство навигации к родителю; это попадает в своего рода круговую зависимость. Есть ли Attribute или трюк, чтобы исключить свойство навигации из сериализации?

Вернуть ItemDto (без свойства навигации) в PostDto,

Да, вы должны включить явно, как это.

GetAll().Include(i => i.ChildEntities)

Вы должны включить дочерние объекты вручную. Это ленивая загрузка по дизайну.

В Abp.io все, что вам нужно (это необходимо добавить в PostService, унаследованный от CrudAppService):

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

Для кого это работает с AsyncCrudAppService, и у вас есть два разных списка дочерних:

Ниже, чтобы получить конкретный родительский объект со списком дочерних элементов

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

Другие вопросы по тегам