In meiner Bewerbung habe ich Dozenten und sie haben eine Liste von Kursen, die sie unterrichten können. Wenn ich einen Kurs lösche, möchte ich die Verbindung zu Dozenten entfernen. Hier ist der Code:
public void RemoveCourse(int courseId)
{
using (var db = new AcademicTimetableDbContext())
{
var courseFromDb = db.Courses.Find(courseId);
var toRemove = db.Lecturers
.Where(l => l.Courses.Contains(courseFromDb)).ToList();
foreach (var lecturer in toRemove)
{
lecturer.Courses.Remove(courseFromDb);
}
db.SaveChanges();
}
}
aber es geht nicht. Ich bekomme
NotSupportedException: Konnte keinen konstanten Wert vom Typ
Course
erstellen. In diesem Zusammenhang werden nur Grundtypen oder Aufzählungstypen unterstützt.
Was mache ich falsch?
Sie können Contains
nicht mit nicht primitiven Werten verwenden. Tun
Where(l => l.Courses.Select(c => c.CourseId).Contains(courseId)
(oder das von Ihnen verwendete Id-Feld).
Wenn Sie einen DbContext verwenden, können Sie die .Local-Auflistung abfragen. Der Operator == funktioniert auch mit Objekten:
public void RemoveCourse(int courseId)
{
using (var db = new AcademicTimetableDbContext())
{
var courseFromDb = db.Courses.Find(courseId);
db.Lecturers.Load() //this is optional, it may take some time in the first load
//Add .Local to this line
var toRemove = db.Lecturers.Local
.Where(l => l.Courses.Contains(courseFromDb)).ToList();
foreach (var lecturer in toRemove)
{
lecturer.Courses.Remove(courseFromDb);
}
db.SaveChanges();
}
}
Die .Local ist eine ObservableCollection, sodass Sie alles vergleichen können, was Sie möchten (nicht auf SQL-Abfragen beschränkt, die keinen Objektvergleich unterstützen). Um sicherzustellen, dass Sie alle Objekte in der .Local-Sammlung erhalten, können Sie die db.Lecturers.Load () -Methode aufrufen, bevor Sie .Local aufrufen, wodurch alle Datenbankeinträge in die Local-Sammlung aufgenommen werden.
Die Courses
-Auflistung der unteren Zeile sollte null oder leer sein.
var toRemove = db.Lecturers
.Where(l => l.Courses.Contains(courseFromDb)).ToList();
Dies kann auch passieren, wenn Sie einen Func<T, bool>
an Where () übergeben, um eine dynamische Bedingung wie hier hier .__ zu schreiben. Aus irgendeinem Grund kann der Delegat nicht in SQL übersetzt werden.
Sie können komplexe Typen nicht vergleichen, wenn Sie nicht angegeben haben, was Sie für Gleichheit bedeuten.
Wie im Ausnahmedetail angegeben, müssen Sie die primitiven Werte überprüfen (in Ihrem Fall Integer).
Verwenden Sie stattdessen besser die Methode Any()
.
var toRemove = db.Lecturers
.Where(l => l.Courses.Any(p=>p.Id == courseFromDb.Id)).ToList();