简体   繁体   中英

includeDetails not working in ABP Framework

I have a simple project (ABP version: 3.1.2, Database: EF Core).

I run GetAsync :

var author = await _authorRepository.GetAsync(id, includeDetails: true);

But author.Films was not included. What may I have forgotten?

Author ( AggregateRoot ):

public class Author : FullAuditedAggregateRoot<Guid>
{
    public string Name { get; private set; }
    public DateTime BirthDate { get; set; }
    public string ShortBio { get; set; }
    public List<Film> Films { get; set; }
    private Author()
    {
        Films = new List<Film>();
        /* This constructor is for deserialization / ORM purpose */
    }
    internal Author(
        Guid id,
        [NotNull] string name,
        DateTime birthDate,
        [CanBeNull] string shortBio = null)
        : base(id)
    {
        Name = name;
        BirthDate = birthDate;
        ShortBio = shortBio;
        Films = new List<Film>();
    }
}

Film ( Entity ):

public class Film : Entity<Guid>
{
    public virtual Guid AuthorId { get; internal set; }
    public string Name { get; set; }
}

SeedAsync in DataSeeder class (I checked whether data exists in database after DbMigrator ran, there are these data in tables as expected):

public async Task SeedAsync(DataSeedContext context)
{
    if (await _authorRepository.GetCountAsync() == 0)
    {
        var authorId = _guidGenerator.Create();
        await _authorRepository.InsertAsync(
            new Author(authorId, "J. R. R. Tolkien", DateTime.Now.AddYears(-60), "bio1"),
            autoSave: true
        );
        await _filmRepository.InsertAsync(
            new Film { AuthorId = authorId, Name = "The Return of the King1" },
            autoSave: true);
        await _filmRepository.InsertAsync(
            new Film { AuthorId = authorId, Name = "The Return of the King2" },
            autoSave: true);
        await _filmRepository.InsertAsync(
            new Film { AuthorId = authorId, Name = "The Return of the King3" },
            autoSave: true);
    }
}

AuthorAppService :

public class AuthorAppService : BookStoreAppService, IAuthorAppService
{
    private readonly IAuthorRepository _authorRepository;
    private readonly AuthorManager _authorManager;
    public AuthorAppService(
        IAuthorRepository authorRepository,
        AuthorManager authorManager)
    {
        _authorRepository = authorRepository;
        _authorManager = authorManager;
    }

    public async Task<AuthorDto> GetAsync(Guid id)
    {
        var author = await _authorRepository.GetAsync(id, includeDetails: true);
        return ObjectMapper.Map<Author, AuthorDto>(author);
    }
}

From https://docs.abp.io/en/abp/latest/Best-Practices/Entity-Framework-Core-Integration :

  • Do create a IncludeDetails extension method for the IQueryable<TEntity> for each aggregate root which has sub collections .

  • ...

  • Do override WithDetails method of the repository for aggregates root which have sub collections .

public static class AuthorEfCoreQueryableExtensions
{
    public static IQueryable<Author> IncludeDetails(this IQueryable<Author> queryable, bool include = true)
    {
        if (!include)
        {
            return queryable;
        }

        return queryable
            .Include(x => x.Films);
    }
}

public class AuthorRepository : EfCoreRepository<IMyDbContext, Author, Guid>, IAuthorRepository
{
    ...

    public override IQueryable<Author> WithDetails()
    {
        return GetQueryable().IncludeDetails(); // Uses the extension method defined above
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM