64

在我的应用程序中,我有讲师,他们有他们可以教授的课程列表,当我删除课程时,我想删除与讲师的连接。这是代码:

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。此上下文仅支持原始类型或枚举类型。

我究竟做错了什么?

4

5 回答 5

90

您不能Contains与非原始值一起使用。做

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

(或您使用的 Id 字段)。

于 2012-11-15T20:46:16.420 回答
8

如果您使用的是 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 集合。

于 2013-07-04T16:52:08.157 回答
1

以下行的Courses集合应为空或为空。

 var toRemove = db.Lecturers
                        .Where(l => l.Courses.Contains(courseFromDb)).ToList();
于 2017-11-03T06:11:28.477 回答
0

当您将 a 传递Func<T, bool>给 Where() 作为一种编写动态条件的方式时,也会发生这种情况,例如此处 由于某种原因,委托无法转换为 SQL。

于 2018-10-24T18:39:38.007 回答
0

如果您没有指定相等的含义,则无法比较复杂类型。

正如异常细节所说,您需要检查原始值(例如您的情况下的整数)。

最好改用Any()方法。

var toRemove = db.Lecturers
     .Where(l => l.Courses.Any(p=>p.Id == courseFromDb.Id)).ToList();
于 2019-08-30T07:14:56.600 回答