实体框架 - DbSet包含空实体

时间:2016-09-21 11:07:37

标签: c# entity-framework dbset

我想在DbSet中添加一个实体,并在Entity Framework Code First中保存上下文中的更改。我有大学DbSet:

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

我有5个课程在使用 - 学期;学院;部门;大学;和学生。他们的构造方法如下:

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>();
}

我从以前的表格中获得学生实体(登录该计划的学生)。当我试图添加由组合框和文本框填充的实体时,我意识到大学DbSet正在填充我想添加的真实实体,但也填充了一个空的大学实体。我的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而制作的实体创作。我试图在大学DbSet中找到空值并删除它们但我不能这样做。截图如下:

DbSet

其他DbSet没有这个问题。我不知道如何摆脱这个问题。任何帮助都会受到赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

答案可能是你将大学直接添加到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:域驱动设计中的聚合根的概念将通过仅添加通过其访问相关实体的根实体来解决此问题。