it-swarm.com.de

LINQ, Konstanter Wert des Typs XXX kann nicht erstellt werden. In diesem Zusammenhang werden nur Grundtypen oder Aufzählungstypen unterstützt

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?

56
pawel1708hp

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

78
Gert Arnold

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.

6
Hannish

Die Courses-Auflistung der unteren Zeile sollte null oder leer sein.

 var toRemove = db.Lecturers
                        .Where(l => l.Courses.Contains(courseFromDb)).ToList();
1
Chamath Jeevan

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.

0
shrutyzet

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();
0
Aryan Firouzian