web-dev-qa-db-ja.com

LINQ、タイプXXXの定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています

私のアプリケーションには講師がいて、教えることができるコースのリストがあります。また、コースを削除するときは、講師とのつながりを削除します。コードは次のとおりです。

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型の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。

何が間違っていますか?

60
pawel1708hp

Containsを非プリミティブ値と共に使用することはできません。行う

Where(l => l.Courses.Select(c => c.CourseId).Contains(courseId)

(または使用するIdフィールド)。

86
Gert Arnold

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コレクションに取り込むことができます。

7
Hannish

以下の行のCoursesコレクションは、nullまたは空でなければなりません。

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

これは、次のような動的条件を記述する方法としてFunc<T, bool>をWhere()に渡すときにも発生する可能性があります here 何らかの理由でデリゲートをSQLに変換できません。

0
shrutyzet

平等の意味を指定していない場合、複合型を比較す​​ることはできません。

例外の詳細にあるように、プリミティブ値(ケースのIntegerなど)を確認する必要があります。

代わりにAny()メソッドを使用することをお勧めします。

var toRemove = db.Lecturers
     .Where(l => l.Courses.Any(p=>p.Id == courseFromDb.Id)).ToList();
0
Aryan Firouzian