LINQ,无法创建XXX类型的常量值。在此上下文中仅支持基元类型或枚举类型

时间:2012-11-15 20:24:11

标签: c# entity-framework linq

在我的申请中,我有讲师,他们有可以教授的课程清单,当我删除课程时,我想删除与讲师的联系。这是代码:

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的常量值。在此上下文中仅支持原始类型或枚举类型。

我做错了什么?

5 个答案:

答案 0 :(得分:82)

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

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

(或您使用的Id字段)。

答案 1 :(得分:6)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

最好使用Any()方法。

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