2016-09-21 2 views
1

Ich bin bereit, eine Entity zu DbSet hinzuzufügen und Änderungen im Kontext in Entity Framework Code zuerst zu speichern. Ich habe Universität DbSet:Entity Framework - DbSet enthält Null Entity

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

Ich habe 5 Klasse im Einsatz - Begriff; Fakultät; Abteilung; Universität; und Student. Ihre Konstruktormethoden sind wie:

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

erhalte ich eine Student Einheit aus früheren Formen, (Schüler, die im Programm angemeldet). Wenn ich versuche, Entitäten hinzuzufügen, die mit Comboboxen und Textfeldern gefüllt sind, habe ich festgestellt, dass Universities DbSet die reale Entität füllt, die ich hinzufügen wollte, aber auch eine leere Entität der Universität füllt. Meine Id-Werte werden nicht automatisch erhöht, deshalb inkrementiere ich sie manuell. Mein Code:

erstellen Fakultät Entity:

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

Abteilung Entity erstellen:

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

Universität Entity erstellen:

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

erstellen Begriff Entity:

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; 

Und mein DbSet Zugänge:

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

Aber ich habe Fehler bei der Überprüfung fehlgeschlagen, so versuche ich, catch-Blöcke verwendet Ausnahme zu analysieren. Ich erkannte, dass mein Unversity DbSet eine leere Universität enthält. Wenn ich debugge, merkte ich, dass sie von Entity-Kreationen kommen, die ich zum Zweck der Bestimmung der ID der Entitäten mache. Ich versuchte, die Nullwerte in Universitäten DbSet zu erreichen und sie entfernen, aber ich konnte es in diesem way.The Screenshot nicht tun, ist unten:

DbSet

Andere DbSet die haben nicht so problem.I don‘ t wissen, was zu tun ist, um dieses Problem loszuwerden.Any hilft würde schätzen. Danke.

+1

Die Antwort möglicherweise ist, dass Sie die Universität einmal direkt in das DbSet hinzufügen, aber dann wieder durch die Beziehung zwischen Fakultäten und der Universität. Das Konzept einer Aggregatwurzel in einem domänengestützten Entwurf würde dies berücksichtigen, indem nur der Stamm hinzugefügt wird, der implizit die zugehörigen Entitäten hinzufügt. – strongbutgood

+1

Die Konstrukteure von Fakultät, Semester und Abteilung schaffen genau diese Universität. Es scheint, dass einige von ihnen nicht gesetzt wurden, bis diese Objekte angehängt wurden, versuchen Sie, diese Zuordnungen zu entfernen, da Sie sowieso die Universität als Ganzes eingestellt haben. – DevilSuichiro

+0

Ich habe es geschafft! Ich tat als @DevilSuichiro sagte.Ich entfernte Universität ordnet, dass in Konstruktoren stattfindet und Problem gelöst! Danke für den Rat! Ich werde _Aggragate Root in Domain Driven Design_ lernen, sobald ich kann.Vielen Dank für Ihren Kommentar und Anleitung "** strong butgood **" –

Antwort

1

Die Antwort möglicherweise ist, dass Sie die Universität einmal direkt in das DbSet hinzufügen, aber dann wieder durch die Beziehung zwischen Fakultäten und der Universität. Wenn Sie über DbSet.Add(entity) eine Entität zu einem Kontext hinzufügen, wird das gesamte Diagramm dieser Entität mit dem zugrunde liegenden Kontext verknüpft, und alle Entitäten in dieser Grafik werden auf den Status Hinzugefügt gesetzt, außer wenn die Stammentität bereits hinzugefügt wurde. Wenn Sie Ihre Fakultät, Ihren Begriff und Ihre Fakultät mit der Universität verbinden und dann alle vier zum Kontext hinzufügen, erhalten Sie mehr als die eine Universität, die Sie erwartet haben. Ich kann nicht 100% ig sicher sein, was vor sich geht, weil Sie sagen, dass Sie die ID-Werte manuell generieren und Sie nicht Ihr gesamtes Modell offengelegt haben.

Es gibt drei Möglichkeiten, wie ich sehen Sie dieses Problem lösen können:

1: die Beziehung Zuweisung Ändern Sie die UniversityId auf Fakultät, Laufzeit und Abteilung zu verwenden, oder die Zuordnung ganz entfernen und auf die Beziehungen verlassen, wie durch die zugewiesene Sammlungen:

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: Verwenden Sie die Universität in den Kontext nicht hinzufügen

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

3: das Konzept eines Aggregate Wurzel in Domäne D Riven Design würde sich damit befassen, indem nur die Root-Entität hinzugefügt wird, über die auf die zugehörigen Entitäten zugegriffen wird.

+0

dies ist nicht ganz richtig. Die Anweisung .Add fügt die Struktur zum Objektgraphen hinzu (ChangeTracker, nicht tatsächlich DbSet), es sei denn, das Objekt befindet sich bereits im Kontext. Dadurch vermeiden Sie, dass mehrere Objekte an die DbSets angehängt werden, denen die Navigationseigenschaften nicht zugeordnet werden. Außerdem schlägt Ihre Antwort mehrere Quellen entsprechender Objektbäume vor, wodurch jede Speichermethode unnötig komplex wird. – DevilSuichiro

+0

@DevilSuichiro Punkte bemerkt, werde ich aktualisieren, um zu klären, was passiert, genauer. – strongbutgood

Verwandte Themen