首页 > 解决方案 > 实体框架核心:没有外键的一对多?

问题描述

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

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

现在我想通过LINQ实体获取一个项目列表,当我在它的时候,获取每个任务的列表。我通过创建一个自定义类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 创建的(只有Project其中CustomProject一个),我不知道是否有办法告诉EF 类似于“嘿,我手动创建的这个自定义类与数据库中的这个表相关并以这种方式映射它......”。

PS我听说它就像创建另一个部分类但我不知道......

谢谢

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

解决方案


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

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

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

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

您可以通过在模型中添加带有注释CustomProject的集合来避免创建模型,如下所示 -TaskProject[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; }
}

如果没有属性 EF 将基于导航属性in和外键属性[NotMapped]创建一对多关系。将阻止这种情况。TasksProjectProjectIdTask[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();

推荐阅读