Получить дочерние объекты из 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);
}