【问题标题】:Accessing child object from parent object in EF Core从 EF Core 中的父对象访问子对象
【发布时间】:2020-02-10 14:54:22
【问题描述】:

我已经搜索了整个网络,但仍然无法正常工作。

我需要的是一个如下所示的简单列表:

  • 父名1
  • 子名1
  • 子名2
  • 父名2
  • 子名3

我有一个父对象表和一个子对象表。在 Child 对象表中,有一个外键 ParentId。

现在,我使用强类型 ViewModel 和 Intellisense 甚至通过 Parent.Child.Property 建议子属性,但是当我运行程序时,我得到一个“NullReferenceException:对象引用未设置为对象的实例”。 .

我的父类如下所示:

    public class EmployeeArea
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ID { get; set; }

        public int? StudioCode { get; set; }

        public string AreaName { get; set; }

        public List<EmployeeName> EmployeeNames { get; set; }
    }
}

我的 Child 类看起来像这样:

    public class EmployeeName
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ID { get; set; }

        public string Name { get; set; }

        public int AreaId { get; set; }
    }
}

我需要在 DbContext 模型构建器中做些什么吗?我欢迎任何帮助。谢谢!

【问题讨论】:

  • 从数据库中提取数据的查询是什么样的?此外,我在这里看不到任何设置外键关系的属性。
  • 我使用的是 EF Core,所以我只是创建了类并将它们添加为 DbSet。这一切都很好,但只有当我不需要外键引用的任何东西时。实体框架还应该自己创建一个影子 FK 属性。至少文档是这么说的。

标签: c# asp.net-mvc entity-framework asp.net-core


【解决方案1】:

好吧,我看不到您的查询,但我建议您执行以下操作。 首先,外键应该是:

public int EmployeeAreaId {get; set;}

那么您有两个选项可以从数据库中获取数据。 如果您使用的是 EF,那么:

db.EmployeeArea.Include(e => e.EmployeeName).ToList();

这将返回一个包含子列表的employeeArea 列表。

使用 Linq 会像:

var employeeArea = (from e in db.EmployeeArea
                    select new EmployeeArea
                               {
                                  Id = e.Id
                                  // continue populating the model properties
                                  EmployeeNames = db.EmployeeName.Where(e => 
                                  e.EmployeeAreaId == e.Id).ToList(),
                               }).ToList()

请原谅这里的任何错字。希望对您有所帮助。

确保在循环访问父母时检查他们的子列表是否为null

【讨论】:

  • 好的,所以我需要在控制器中进行查询,将其传递给我的 Viewmodel,然后在视图中使用它。然后我怎样才能按父母过滤孩子?当我列出我刚刚使用的孩子时(foreach var employeeName in model.NameModel),以及列出我使用的父母(foreach var employeeArea in model.AreaModel)。但我不知道如何让孩子按父母分组。该死的,我可能太愚蠢了。我已经使用 EF 和 ASP Core 工作了几个月,但我无法理解这一点。
  • 很简单,在遍历父母时,foreach(var employee in EmployeeArea) {// 对孩子做一些事情,比如: foreach(var employeeName in employee.EmployeeName) { // 这里得到该父母的所有孩子}}
  • 我在那里放了一个断点,每个父区域的 List EmployeeNames 为空。孩子们只是没有得到参考。如果我有任何有用的东西,我会在这里发表评论。
  • 一定要正确命名,比如外键应该像我回答的第一行一样,否则,EF 将无法将其作为外键读取。
  • 你的命名是对的!现在它可以工作了,但是当父区域没有子区域时,它会抛出一个错误,即存在对空对象的引用。但多亏了你,主要问题得到了解决。非常感谢。
【解决方案2】:

您必须首先通过覆盖 OnModelCreating 或按照约定正确定义外键:

public int EmployeeAreaId {get; set;}

如果您使用的是强类型 ViewModels,则需要使用 EFCore Projections(https://entityframeworkcore.com/querying-data-projection),代码将如下所示(替换为您的视图模型名称):

db.EmployeeAreas.Select(e => new YourViewModel{
  ParentName = e.AreaName,
  ChildNames = e.EmployeeNames.Select(en => new List<string>{
    EmployeeName = en.Name
  }).ToList();
}).ToList();

如果这是 Json,它将如下所示:

[
  {
    ParentName : "ParentName1",
    ChildNames ; ["ChildName1","ChildName2"]
  },
  {
    ParentName : "ParentName2",
    ChildNames ; ["ChildName3"]
  }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 2020-10-10
    • 2013-04-28
    • 2018-02-18
    相关资源
    最近更新 更多