Dans ma demande, j'ai des conférenciers et ils ont la liste des cours qu'ils peuvent enseigner et lorsque je supprime un cours, je souhaite supprimer tout lien avec les conférenciers. Voici le 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();
}
}
mais ça ne marche pas. Je reçois
NotSupportedException: impossible de créer une valeur constante de type
Course
. Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte.
Qu'est-ce que je fais mal?
Vous ne pouvez pas utiliser Contains
avec des valeurs non primitives. Faire
Where(l => l.Courses.Select(c => c.CourseId).Contains(courseId)
(ou le champ Id que vous utilisez).
Si vous utilisez un DbContext, vous pouvez interroger la collection .Local et l'opérateur == fonctionnera également avec les objets:
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();
}
}
Le .Local est une ObservableCollection, vous pouvez donc comparer tout ce que vous voulez à l'intérieur (non limité aux requêtes SQL qui ne prennent pas en charge la comparaison d'objet). Pour vous assurer que tous vos objets appartiennent à la collection .Local, vous pouvez appeler la méthode db.Lecturers.Load () avant d'appeler .Local, qui regroupe toutes les entrées de la base de données dans la collection Local.
La collection Courses
de la ligne ci-dessous doit être nulle ou vide.
var toRemove = db.Lecturers
.Where(l => l.Courses.Contains(courseFromDb)).ToList();
Cela peut également se produire lorsque vous passez un Func<T, bool>
à Where () comme moyen d'écrire une condition dynamique comme ici ici .__ Pour une raison quelconque, le délégué ne peut pas être traduit en SQL.
Vous ne pouvez pas comparer un type complexe si vous n'avez pas précisé ce que vous voulez dire par égalité.
Comme le dit le détail des exceptions, vous devez vérifier les valeurs primitives (comme Integer dans votre cas).
Et il vaut mieux utiliser la méthode Any()
à la place.
var toRemove = db.Lecturers
.Where(l => l.Courses.Any(p=>p.Id == courseFromDb.Id)).ToList();