includeDetails 在 ABP 框架中不起作用

includeDetails not working in ABP Framework

我有一个simple project(ABP版本:3.1.2,数据库:EF Core)。

我运行GetAsync:

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

author.Films 未包括在内。我可能忘记了什么?

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(我检查了DbMigrator 运行之后数据库中是否存在数据,表中确实有这些数据) :

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

来自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
    }
}