简体   繁体   中英

EF Core .ThenInclude does not include foreign entity and causes query to retrieve nothing

I have an EF Core project here, but I do have difficulties with multilevel includes. I'm trying to query entries which do relate like this:

  1. There's a mapping table for "friend" relationships from accountid to accountid. So layer one is this mapping entity.

  2. The IDs of the accounts in the mapping table are foreign keys relating to the respective Account entity.

  3. Within the account entity, there's a foreign key to an account online state entity.

So tl;dr; FriendsMappingTable -> Account -> AccountOnlineState .

Here's the code I do use:

public Task<List<TEntity>> Read(Expression<Func<TEntity, bool>> predicate, params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] foreignIncludes) 
{
    return RunInContextWithResult(async dbSet =>
    {
        var query = dbSet.Where(predicate);

        query = foreignIncludes.Aggregate(query, (current, include) => include(current));

        return await query.ToListAsync();
    });
 }

private async Task<List<TEntity>> RunInContextWithResult([NotNull] Func<DbSet<TEntity>, Task<List<TEntity>>> dbFunc)
{
    await using var ctx = GetContext();

    return await dbFunc(ctx.Set<TEntity>());
}

and here's my call to that:

var friends = await m_friendsMappingRepository.Read(
            x => x.Id == sessionContext.Account.Id,
            x => x.Include(y => y.Friend).ThenInclude(y => y.AccountOnlineStateEntity));

However, with this setup, the query will just return nothing at all. If I remove the .ThenInclude() , it will at least return a corresponding friend entity for the given account, with the OnlineState entity set to null.

Here are the (stripped down) entities:

public interface IEntity<TKeyType>
{
    [NotNull]
    [Key]
    [Column("Id")]
    public TKeyType Id { get; set; }
}

[Table("FriendsMapping")]
public class FriendsMappingEntity : IEntity<int>
{
    [ForeignKey("Account")]
    public int Id { get; set; }

    public AccountEntity Account { 
        get; 
        [UsedImplicitly] private set;
    }

    [Column("FriendId")]
    [ForeignKey("Friend")]
    public int FriendId { get; set; }

    public AccountEntity Friend
    {
        get; 
        [UsedImplicitly] private set;
    }
}

public class AccountEntity : IEntity<int>
{
    [ForeignKey("AccountOnlineStateEntity")]
    public int Id { get; set; }

    [CanBeNull]
    public AccountOnlineStateEntity AccountOnlineStateEntity { get; set; }

    [NotNull]
    public List<FriendsMappingEntity> FriendsTo { get; set; }

    [NotNull]
    public List<FriendsMappingEntity> FriendsFrom { get; set; }
}

public class AccountOnlineStateEntity : IEntity<int>
{
    public int Id { get; set; }

    [Column("OnlineState")]
    public AccountOnlineState OnlineState { get; set; }
}

Update

Building on Ivan's suggestion, add an InverseProperty and remove the ForeignKey from Account.Id.

    //[ForeignKey("AccountOnlineStateEntity")]
    public int Id { get; set; }

    [CanBeNull]
    [InverseProperty("Account")
    public AccountOnlineStateEntity AccountOnlineStateEntity { get; set; }

And add a property to AccountOnlineStateEntity

    [ForeignKey("Id")]
    public AccountEntity Account { get; set; }

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