实体框架核心:一对多没有外键?

时间:2021-03-17 14:02:58

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

我有一个 ASP MVC .NET Core (C#) 项目,由于业务原因,SQL 表不能有外键,因此,EF 模型不映射关系 (entity.HasMany ....)。

假设 EF 为实体 Project 生成一个模型,为 Task 生成一个模型。我想要他们两个之间的关系。一个 Project 有多个 Tasks,一个 Task 属于一个 Project。任务在数据库中有项目 ID(但请记住,它没有设置为 FK)。

现在我想通过 LINQ 到 Entity 获取项目列表,当我在做的时候,获取每个项目的任务列表。我通过创建一个自定义类 CustomProject(除了由 EF 创建的类)并执行以下操作来实现这一点:

List<CustomProject> projects = (from p in db.Project
                                select new CustomProject {
                                   //Properties
                                   Tasks = db.Tasks.Where(t => t.IdProject == p.IdProject).ToList()
                                }).ToList();

问题是,我不想创建自定义类,也不想使用这种表示法,我只想使用 db.Projects.Include("Tasks"),仅此而已。

现在我不介意创建自定义类,但只要我没有几乎相同但由 EF 创建的东西(有 ProjectCustomProject,只有其中一个),我不知道是否有办法告诉 EF 诸如“嘿,我手动创建的这个自定义类与数据库中的这个表相关并以这种方式映射......”。

附言我听说它类似于创建另一个部分类,但我不知道...

谢谢

1 个答案:

答案 0 :(得分:1)

<块引用>

我只想使用 db.Projects.Include("Tasks"),仅此而已...

您不能这样做,因为要使用 Include() 方法,您将需要数据关系(即基于外键的关系)。

<块引用>

问题是,我不想创建自定义类,也不想使用该符号

如果没有基于外键的关系,我认为您没有更多选择更好的表示法 - 您必须使用 Select() 投影。

您可以通过在 CustomProject 模型中添加一组 Task 来避免创建 Project 模型,并使用 [NotMapped] 进行注释,如下所示 -

public class Project
{
    public int Id { get; set; }
    public string Title { get; set; }

    [NotMapped]
    public List<Task> Tasks { get; set; }
}

public class Task
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ProjectId { get; set; }
}

如果没有 [NotMapped] 属性,EF 将基于 Tasks 中的导航属性 ProjectProjectId 中的外键属性 Task 创建一对多关系{1}}。 [NotMapped] 会阻止这种情况发生。

然后您可以使用 Project 模型进行查询,例如 -

List<Project> projects1 = (from p in dbCtx.Projects
                            select new Project
                            {
                                Id = p.Id,
                                Name = p.Name,
                                Tasks = dbCtx.Tasks.Where(t => t.ProjectId == p.Id).ToList()
                            }).ToList();

或者,像 -

List<Project> projects = dbCtx.Projects
    .Select(p => new Project
    {
        Id = p.Id,
        Name = p.Name,
        Tasks = dbCtx.Tasks.Where(t => t.ProjectId == p.Id).ToList()
    }).ToList();