代码之家  ›  专栏  ›  技术社区  ›  Mohammad Shadmehr

Linq渴望加载链实体

  •  1
  • Mohammad Shadmehr  · 技术社区  · 7 年前

    为什么是候选人。在以下所有尝试中,资格始终为空:

    var candidate = await _acceptedOfferRepository.GetAll()
                                                  .Include(c => c.Candidate)
                                                  .Where(ao => ao.Candidate.Id == candidateId && ao.EmployerId.Id == employerId)
                                                  .Select(c => c.Candidate)
                                                  .Include(c => c.Qualification)
                                                  .FirstOrDefaultAsync();
    

    或:

    var candidate = await _acceptedOfferRepository.GetAll()
                                                  .Include(c => c.Candidate.Qualification)
                                                  .Where(ao => ao.Candidate.Id == candidateId && ao.EmployerId.Id == employerId)
                                                  .Select(c => c.Candidate)
                                                  .FirstOrDefaultAsync();
    

    或:

    var candidate = await _acceptedOfferRepository.GetAll()
                                                  .Include(c => c.Candidate)
                                                  .ThenInclude(c => c.Candidate.Qualification)
                                                  .Where(ao => ao.Candidate.Id == candidateId && ao.EmployerId.Id == employerId)
                                                  .Select(c => c.Candidate)
                                                  .FirstOrDefaultAsync();
    
    • 候选人与他/她的关系为1:1 资格

    • 您接受了错误回复。GetAll()返回 IQueryable公司

    我认为FirstOrDefaultAsync()之前的Select()有问题。只要我删除它,它就可以正常工作,并且所有链接实体都已正确加载。但它会返回第一个AcceptedOffer,而我需要候选人!

    2 回复  |  直到 7 年前
        1
  •  1
  •   Ivan Stoev    7 年前

    来自失败尝试的查询分为 Ignored includes 类别:

    如果更改查询,使其不再返回查询开始时的实体类型的实例,则会忽略include运算符。

    它们与链接中的示例非常相似。查询以开始 AcceptedOffer ,但是 Select 将结果类型更改为 Candidate ,因此全部 Include / ThenInclude 都被忽略了。

    我建议的第一件事是将EF Core配置为对忽略的包含抛出异常,如链接中所述:

    optionsBuilder.ConfigureWarnings(warnings => warnings
        .Throw(CoreEventId.IncludeIgnoredWarning));
    

    其次,尝试从要返回的实体开始构建实体返回查询。例如,对于您的示例,它可能是这样的(如果您具有 候选人 接受提供者 和相应的存储库):

    var candidate = await _candidateRepository.GetAll()
        .Include(c => c.Qualification)
        .Include(c => c.AcceptedOffers) // optional
        .Where(c => c.Id == candidateId && 
            c.AcceptedOffers.Any(ao => ao.EmployerId.Id == employerId))
        .FirstOrDefaultAsync();
    
        2
  •  0
  •   Mohammad Shadmehr    7 年前

    这很好:

    var candidate = (await _acceptedOfferRepository.GetAll()
                                              .Include(c => c.Candidate)
                                              .ThenInclude(c => c.Candidate.Qualification)
                                              .Where(ao => ao.Candidate.Id == candidateId && ao.EmployerId.Id == employerId)
                                              .FirstOrDefaultAsync())?.Candidate;
    

    但是仍然不太清楚为什么Select()没有加载限定!