实体框架中未填充外键

Dar*_*rds 3 c# entity-framework-core .net-core asp.net-core

我无法正确更新应该链接我的两个实体的表。更详细地解释......我有两个实体ClassTeacher,它们的关系为:

  1. 老师可以分配到多个班级
  2. 班级只能有一位老师。

下面是这两个实体。

public class Teacher
{
    [Required, Key]
    public Guid Id { get; private set; }
    [StringLength(50)]
    public string Name { get; set; }
    public string Email { get; set; }
    public List<Class> Classes = new List<Class>();

    public Teacher()
    {
        Id = new Guid();
    }

    public Teacher(Guid id)
    {
        Id = id;
    }

    public void AssignClass(Class newClass)
    {
        Classes.Add(newClass);
    }
}

public class Class
{
    [Required, Key]
    public Guid Id { get; private set; }
    [Required, StringLength(20)]
    public string Name { get; set; }
    [Required, Range(5, 30)]
    public int Capacity { get; set; }
    public Teacher Teacher { get; set; }
    public IEnumerable<StudentClass> StudentClasses { get; set; }

    public Class()
    {
        Id = new Guid();
    }

    public Class(Guid id)
    {
        Id = id;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我生成迁移时,我按预期在 Classes 表中得到了一个外键TeacherId。这是 SQL:

CREATE TABLE [dbo].[Classes] (
[Id]        UNIQUEIDENTIFIER NOT NULL,
[Name]      NVARCHAR (20)    NOT NULL,
[Capacity]  INT              NOT NULL,
[TeacherId] UNIQUEIDENTIFIER NULL,
CONSTRAINT [PK_Classes] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Classes_Teachers_TeacherId] FOREIGN KEY ([TeacherId]) REFERENCES [dbo].[Teachers] ([Id])
);
GO
CREATE NONCLUSTERED INDEX [IX_Classes_TeacherId]
ON [dbo].[Classes]([TeacherId] ASC);
Run Code Online (Sandbox Code Playgroud)

我的DBContext派生类如下所示:

public class SchoolDatabaseContext : DbContext
{
    public DbSet<Student> Students { get; private set; }
    public DbSet<Class> Classes { get; private set; }
    public DbSet<Teacher> Teachers { get; private set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

    }

    public SchoolDatabaseContext(DbContextOptions<SchoolDatabaseContext> options) : base(options)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这些实体还没有配置。我使用 DI 将DbContext 提供给控制器,一切看起来都很好。

我的目标是 DDD 类型的结构,但为了使这个问题更容易调试,我已经将所有内容都剥离回控制器,因此它基本上是... controller => DbContext

这是我在控制器中的代码:

[HttpPost]
    [Route("assign-teacher-to-class")]
    public async Task<IActionResult> AssignClass([FromBody] AssignTeacherToClass assignTeacherToClass)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var teacher = await schoolDatabaseContext.Teachers.FindAsync(assignTeacherToClass.TeacherId);

        var classToAssign = await schoolDatabaseContext.Classes.FindAsync(assignTeacherToClass.ClassId);


        teacher.AssignClass(classToAssign);

        schoolDatabaseContext.Entry(teacher).State = EntityState.Modified;

        await schoolDatabaseContext.SaveChangesAsync();

        return Ok(teacher);
}
Run Code Online (Sandbox Code Playgroud)

当我通过帖子正文中的 id 进行调试时,它们被正确分配给 DTO AssignClass并且调用DbContext以查找每种类型(教师和班级)的数据都很好。然后我在我的老师类型中调用一个方法将类添加到List Classes属性(请参阅开头的教师实体代码以供参考),然后我使用DbContext方法和此处定义的问题保存更改在任何阶段都没有TeacherId在调试/完成时更新数据库。我已经尝试了所有我能想到的方法,例如以不同的方式实例化集合、更改集合类型、寻找可能有助于以这种方式映射这些实体的配置、剥离所有额外层、更改属性和类的可访问性等等。

任何帮助都将不胜感激,因为我在这个问题上有点失败,我觉得这种关系应该是相当直接的。我实际上能够让我的多对多工作与桥梁课程一起工作,所以我很惊讶被困在这个课程上:(

谢谢

Y S*_*oli 7

尝试这个:

 var teacher = await schoolDatabaseContext.Teachers.Include(x => x.Classes).SingleOrDefaultAsync(x => x.Id == assignTeacherToClass.TeacherId);
Run Code Online (Sandbox Code Playgroud)

我认为不会teacher.ClassesDbContext其他人跟踪。