Entity Framework Core - рекурсивное связывание родитель / потомок - PullRequest
0 голосов
/ 09 октября 2018

У меня есть таблица «account», которая содержит строковый внешний ключ («parent_guid») для его «родительской» учетной записи (если она существует).Я хотел бы создать сущность, которая знает своего родителя, а также всех его потомков.

Вот моя сущность:

[Table(name:"accounts")]
public class Account
{
    [Key]
    public string Guid { get; set; }
    public string Name { get; set; }

    [Column("guid")]
    public string accountGuid { get; set; }

    [Column(name: "parent_guid")]
    public string parentGuid { get; set; }

    [ForeignKey("parentGuid")]
    public Account Parent { get; set; }

    [InverseProperty("Parent")]
    public ICollection<Account> Children { get; set; }
}

Вот мой dbContext:

public DbSet<Split> Splits { get; set; }
public DbSet<Account> Accounts { get; set; }

public ReportContext(DbContextOptions<ReportContext> options)
    : base(options)
    { }

Мой запрос выполняется через контекст 'split' в качестве исходной таблицы, но в итоге я возвращаю учетные записи.Может быть, есть лучший способ?

Когда я запрашиваю учетную запись по Guid, я получаю результат, но «Parent» и «Children» всегда равны нулю, даже если «parentGuid» содержит правильное значение, и яподтвердили, что должны быть дочерние записи.

Есть идеи, как заставить эту работу работать, используя аннотации или свободный API?

1 Ответ

0 голосов
/ 09 октября 2018

Да, EFCore требует явного включения реляционных сущностей.

var accounts = await dbContext.Accounts.include(account => account.Parent)
                                       .include(account => account.Children)
                                       .ToListAsync();

РЕДАКТИРОВАТЬ

В соответствии с изменениями к вопросу, это один из способов Стремительная загрузка реляционные сущности, но я не могу говорить об эффективности этого запроса, не зная отношений и индексов.

public IQueryable<Split> 
  FindAllByAccountGuidsPostedBefore(IEnumerable<string> accounts, 
                                                       DateTime endDate) {
  using (reportContext) { 
     return reportContext.Splits.Include(s => s.Account)
                                .ThenInclude(a => a.Parent)
                                .ThenInclude(a => a.Children)
                                .Where(s => accounts.Contains(s.Account.Guid) 
                                 && s.Transaction.postDate < endDate); 
     } 
} 

Один из способов получить эту информацию - посмотреть на консоль, когда этот запрос выполняется, чтобы найти SQLзаявление (я), которое это производит, или спрашивая кого-то, кто более опытен в реляционных базах данных:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...