【问题标题】:Query does not return child collections查询不返回子集合
【发布时间】:2016-08-08 21:02:10
【问题描述】:

我仍然对此感到困惑,为什么每个“类别”项目都返回空的“任务”集合。我确实在数据库中有数据,我缺少什么?

public class ApplicationUser : IdentityUser
{
    public ICollection<Category> Categories { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public DateTime Timestamp { get; set; }

    public ICollection<Task> Tasks { get; set; }
}

public class Task
{
    public int TaskId { get; set; }
    public string Name { get; set; }
    public DateTime Timestamp { get; set; }
}

这里是查询:

public IEnumerable<Category> GetAllForUser(string name)
{
    return _ctx.Users.Where(x => x.UserName == name)
                     .SelectMany(x => x.Categories)
                     .Include(x => x.Tasks).ToList();    
}

【问题讨论】:

    标签: entity-framework linq entity-framework-core


    【解决方案1】:

    您的查询属于Ignored Includes 案例:

    如果您更改查询以使其不再返回查询开始时使用的实体类型的实例,则包含运算符将被忽略。

    如链接中所述,如果您将以下内容添加到您的 DbContext OnConfiguring

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

    然后 null 集合你会得到 InvalidOperationException 在错误消息中包含类似这样的内容:

    导航的包含操作:“x.Tasks”被忽略,因为目标导航在最终查询结果中不可到达。

    那么如何解决呢?显然,要求是从要为其添加包含的实体开始查询。在您的情况下,您应该从_ctx.Categories 开始。但为了应用相同的过滤器,您需要将Application.Users 的反向导航属性添加到Category 类:

    public class Category
    {
        // ...
        public ApplicationUser ApplicationUser { get; set; }
    }
    

    现在以下将起作用:

    public IEnumerable<Category> GetAllForUser(string name)
    {
        return _ctx.Categories
            .Where(c => c.ApplicationUser.UserName == name)
            .Include(c => c.Tasks)
            .ToList();    
    }
    

    【讨论】:

    • 这是完美的伊万,很好的解释,我已经根据你上面提到的内容进行了测试以完全理解它,你找到了解决方案。我很感激
    【解决方案2】:

    试试这个:

    public IEnumerable<Category> GetAllForUser(string name)
    {
        return _ctx.Users
                    .Include(u => u.Categories)
                    .Include(u => u.Categories.Select(c => c.Tasks))
                    .Where(x => x.UserName == name)
                    .SelectMany(x => x.Categories)
                    .ToList();    
    }
    

    【讨论】:

      【解决方案3】:
      public virtual ICollection<Task> Tasks { get; set; }
      

      【讨论】:

      • 请编辑更多信息。不鼓励使用纯代码和“试试这个”的答案,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。我们在这里努力成为知识的资源。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-22
      • 2013-11-22
      • 2017-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多