私のアプリケーションには講師がいて、教えることができるコースのリストがあります。また、コースを削除するときは、講師とのつながりを削除します。コードは次のとおりです。
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();
}
}
しかし、それは機能しません。私は得る
NotSupportedException:
Course
型の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。
何が間違っていますか?
Contains
を非プリミティブ値と共に使用することはできません。行う
Where(l => l.Courses.Select(c => c.CourseId).Contains(courseId)
(または使用するIdフィールド)。
DbContextを使用している場合、.Localコレクションを照会でき、==演算子はオブジェクトでも機能します。
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();
}
}
.LocalはObservableCollectionであるため、内部で好きなものを比較できます(オブジェクト比較をサポートしないSQLクエリに限定されません)。 .Localコレクション内のすべてのオブジェクトを確実に取得するために、.Localを呼び出す前にdb.Lecturers.Load()メソッドを呼び出して、すべてのデータベースエントリをLocalコレクションに取り込むことができます。
以下の行のCourses
コレクションは、nullまたは空でなければなりません。
var toRemove = db.Lecturers
.Where(l => l.Courses.Contains(courseFromDb)).ToList();
これは、次のような動的条件を記述する方法としてFunc<T, bool>
をWhere()に渡すときにも発生する可能性があります here 何らかの理由でデリゲートをSQLに変換できません。
平等の意味を指定していない場合、複合型を比較することはできません。
例外の詳細にあるように、プリミティブ値(ケースのIntegerなど)を確認する必要があります。
代わりにAny()
メソッドを使用することをお勧めします。
var toRemove = db.Lecturers
.Where(l => l.Courses.Any(p=>p.Id == courseFromDb.Id)).ToList();