Entity Framework - DbSet 包含空实体

Entity Framework - DbSet Contains Null Entity

我正在尝试将实体添加到 DbSet 并在 Entity Framework Code First 中保存上下文中的更改。我有大学数据库集:

public DbSet<University> Universities { get; set; }

我有 5 个 class 在使用 - 术语;学院;部门;大学;和学生。他们的构造方法是这样的:

public Student()
{
    Universities = new List<University>();
    User = new DATABASE.User();
    Terms = new List<Term>();
}
public University()
{
    UniversityFaculties = new List<Faculty>();
    UniversityDepartments = new List<Department>();
    Students = new List<Student>();
}
public Term()
{
    Students = new List<Student>();
    Lessons = new List<Lesson>();
    university = new University();
}
public Faculty()
{
    University = new University();
    Students = new List<Student>();
}
public Department()
{
    University = new University();
    Students = new List<Student>();
}

我从以前的表格中得到一个学生实体(登录程序的学生)。当我尝试添加由组合框和文本框填充的实体时,我意识到 Universities DbSet 正在填充我想要添加的真实实体,但也填充了一个空的 University 实体。我的 Id 值不会自动增加,所以我手动增加它们。我的代码:

创建教师实体:

Faculty f = entities.Faculties.OrderByDescending(o => o.FacultyId).FirstOrDefault();
int newFacultyId = (f == null ? 1 : f.FacultyId + 1);

var faculty = new Faculty();
faculty.FacultyId = newFacultyId;
faculty.FacultyName = FacultyComboBox2.SelectedItem.ToString();

创建部门实体:

Department d = entities.Departments.OrderByDescending(o =>o.DepartmentId).FirstOrDefault();
int newDepartmentId = (d == null ? 1 : d.DepartmentId + 1);

var department = new Department();
department.DepartmentId = newDepartmentId;
department.DepartmentName = DepartmentComboBox3.SelectedItem.ToString();

创建大学实体:

University uni = entities.Universities.OrderByDescending(o => o.UniversityId).FirstOrDefault();
int newUniId = (uni == null ? 1 : uni.UniversityId + 1);

var university = new University();

university.UniversityId = newUniId;
university.UniversityName = UniversityComboBox1.Text;

university.UniversityFaculties.Add(faculty);
university.UniversityDepartments.Add(department);
university.Students.Add(student);

student.Universities.Add(university);
faculty.University = university;
department.University = university;
faculty.Students.Add(student);
department.Students.Add(student);

创建术语实体:

Term t = entities.Terms.OrderByDescending(o => o.TermId).FirstOrDefault();
int newTermId = (t == null ? 1 : t.TermId + 1);

var term = new Term();

term.TermId = newTermId;
term.TermTerm = int.Parse(TermComboBox1.Text);
term.TermYear = int.Parse(YearComboBox1.Text);

term.Students.Add(student);
student.Terms.Add(term);
term.university = university;

还有我的 DbSet 添加:

   entities.Faculties.Add(faculty);
   entities.Departments.Add(department);
   entities.Universities.Add(university);
   entities.Terms.Add(term);
   entities.SaveChanges();

但是我收到验证失败错误,所以我使用 try catch 块来分析异常。我意识到我的大学 DbSet 包含一个空的大学实体。当我调试时,我意识到它们来自我为确定实体 ID 而创建的实体。我试图达到 Universities DbSet 中的空值并删除它们,但我无法做到这一点 way.The 屏幕截图如下:

其他 DbSet 没有那个 problem.I 不知道该怎么做才能摆脱那个 problem.Any 帮助是 appreciate.Thanks。

答案可能是您将大学直接添加到 DbSet 中,然后再通过院系与大学之间的关系添加。

当您通过 DbSet.Add(entity) 将实体添加到上下文时,该实体的整个图都将附加到底层上下文,并且该图中的所有实体都设置为已添加状态,除非根实体已经添加。因此,当您将您的学院、学期和系与大学相关联,然后将所有四个添加到上下文中时,您得到的不仅仅是您预期的一所大学。我不能 100% 确定发生了什么,因为正如您所说,您是手动生成 Id 值并且您没有公开整个模型。

我认为您可以通过三种方式解决此问题:

1:更改关系分配以在 Faculty、Term 和 Department 上使用 UniversityId,或者完全删除分配并依赖于集合分配的关系:

uni = entities.Universities.OrderByDescending(o => o.UniversityId).FirstOrDefault();
int newUniId = (uni == null ? 1 : uni.UniversityId + 1);

var university = new University();
university.UniversityId = newUniId;
university.UniversityName = UniversityComboBox1.Text;

// these lines are sufficient to build the relationships between entities, you don't have to set both sides
university.UniversityFaculties.Add(faculty);
university.UniversityDepartments.Add(department);
university.Students.Add(student);

student.Universities.Add(university);
// use foreign key properties to build the relationship without having large graphs when adding to context
faculty.UniversityId = newUniId;
department.UniversityId = newUniId;

faculty.Students.Add(student);
department.Students.Add(student);

2:不要将大学添加到上下文中

entities.Faculties.Add(faculty);
entities.Departments.Add(department);
// entities.Universities.Add(university);
entities.Terms.Add(term);
entities.SaveChanges();

3:领域驱动设计中聚合根的概念将通过仅添加访问相关实体的根实体来解决这个问题。