插入包含集合导航属性的实体

时间:2019-08-06 13:51:36

标签: insert unique-constraint ef-core-2.0 navigation-properties

我有两节课:

public class Student
{
    public int StudentID { get; set; }
    public List<Course> Courses { get; set; }
}

public class Course
{
    public int CourseID { get; set; }    
    public string Name { get; set; }
}

和上下文:

public class DBContext: DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DBContext(DbContextOptions<DBContext> options) : base(options) { }
}

课程和学生可以彼此独立存在。换句话说,我可以先创建一个课程,然后创建一个学生并将其与该课程相关联。

例如:

var options = new DbContextOptionsBuilder<DBContext>().UseSqlite("Data Source=.\\test.db;");

Course course = null;

using(var context = new DBContext(options.Options))
{
    context.Database.EnsureCreated();
}

using (var context = new DBContext(options.Options))
{
    course = context.Courses.Add(new Course { Name = "Algebra" }).Entity;
    context.SaveChanges();
}

using (var context = new DBContext(options.Options))
{
    var student = context.Students.Add(new Student { Courses = new List<Course> { course } });
    context.SaveChanges();
}

但是,在最后一个上下文范围内,我遇到一个唯一的约束错误。我知道有人说我需要在相同背景下做所有事情。但这在使用例如WebAPI微服务体系结构(StudentService和CourseService)时几乎是不可能的。

那我该如何处理呢?

1 个答案:

答案 0 :(得分:0)

这里的问题是,在最后一个使用块context中,不知道course实例已经在上一个操作中保存了。

我做了一个小测试,发现在第二次使用block调用SaveChanges后,该课程没有从数据库分配的ID。

通常,执行此操作的最常见方法是从需要保存数据的同一上下文中获取实体。这样就可以解决问题。

Course course = new Course { Name = "Algebra" };

using (var context = new DBContext(options.Options))
{
    context.Database.EnsureCreated();
}

using (var context = new DBContext(options.Options))
{
    context.Courses.Add(course);
    context.SaveChanges();
}

using (var context = new DBContext(options.Options))
{
    var courseFromDb = context.Courses.Single(c => c.CourseID == course.CourseID);
    var student = context.Students.Add(new Student { Courses = new List<Course> {courseFromDb}});
    context.SaveChanges();
}
相关问题