实体框架,无法创建类型为“XX”的常量值。此上下文仅支持原始类型或枚举类型

Posted

技术标签:

【中文标题】实体框架,无法创建类型为“XX”的常量值。此上下文仅支持原始类型或枚举类型【英文标题】:Entity Framework, unable to create a constant value of type 'XX'. Only primitive types or enumeration types are supported in this context 【发布时间】:2014-04-27 11:49:57 【问题描述】:

我有一个返回 viewmodel 的方法,定义如下:

if (studentId != null)

    var eduRec = (_context.EducationalRecords.Where(x => x.StudentId == studentId)).ToList();
    var guarnator = (_context.NextOfKinGuarantors.Where(x => x.StudentId == studentId)).ToList();

    model = (from stud in _context.Students
             join lga in _context.LocalGovts
                 on stud.LocalGovtId equals lga.LocalGovtId
             join st in _context.States
                 on lga.StateId equals st.StateId
             join acada in _context.AcademicRecords
                 on stud.StudentId equals acada.StudentId
             join dept in _context.Departments
                 on acada.DepartmentId equals dept.DepartmentId
             join faculty in _context.Falculties
                 on dept.FalcultyId equals faculty.FalcultyId
             join prg in _context.Programmes
                 on acada.ProgrammeId equals prg.ProgrammeId
             join lvl in _context.Levels
                 on acada.LevelId equals lvl.LevelId
             where acada.IsCurrentRecord == true && stud.StudentId == studentId
             select new StudentProfileViewModel()
             
                 ContactAddress = stud.ContactAddress,
                 Department = dept.Name,
                 Disability = stud.Disability,
                 Othernames = stud.Othernames,
                 FirstName = stud.FirstName,
                 Surname = stud.Surname,
                 Programme = prg.Name,
                 RegistrationNumber = stud.RegistrationNumber,
                 Dob = stud.Dob,
                 EducationalRecords = eduRec,
                 Email = stud.Email,
                 Faculty = faculty.Name,
                 Gender = stud.Gender,
                 HomeAddress = stud.HomeAddress,
                 Level = lvl.Name,
                 LocalGoverment = lga.Name,
                 MaritalStatus = stud.MaritalStatus,
                 Phone = stud.Phone,
                 Religion = stud.Religion,
                 StateName = st.Name,
                 NextOfKinGuarantors = guarnator
             ).FirstOrDefault();

当我运行应用程序时,我收到以下错误消息:

无法创建“Portal.Models.EducationalRecord”类型的常量值。此上下文仅支持原始类型或枚举类型

EducationalRecords的定义是一个列表。

【问题讨论】:

我会创建StudentProfileViewModel然后将项目添加到EducationalRecords 属性(这是一个列表)。只是 EF 无法将列表转换为有效的表达式("...仅支持原始类型或枚举类型...")。 Unable to create a constant value of type (type) Only primitive types ('such as Int32, String, and Guid') are supported in this context 的可能重复项 【参考方案1】:

您的 LINQ 语句必须可转换为有效的 SQL 查询,因此您必须小心调用的内容。例如,如果您尝试调用一些用 C# 编写的随机方法,则可能无法转换为有效的 SQL,因此您会收到错误。

在您的情况下,它抱怨尝试使用单独的 LINQ 语句填充 EducationalRecords,这显然无法转换为单个 SQL 语句。

从您的 LINQ 语句中删除这一行:

EducationalRecords = eduRec,

在填充model 后,单独获取EducationalRecords

if (model != null)
   model.EducationalRecords =
      _context.EducationalRecords.Where(x => x.StudentId == studentId)).ToList();

【讨论】:

【参考方案2】:

Grant 已经处理了您发布的代码中的问题,但是对于整个问题有更好的解决方案。使用带有预加载的导航属性。这将使您免于进行三个单独的数据库往返来收集此信息。

Here'sMSDN 信息,了解如何在代码优先、模型优先和数据库优先中创建导航属性。

【讨论】:

以上是关于实体框架,无法创建类型为“XX”的常量值。此上下文仅支持原始类型或枚举类型的主要内容,如果未能解决你的问题,请参考以下文章

无法创建类型为“EShop.ClassLibrary.ProductType”的常量值。此上下文仅支持原始类型或枚举类型

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

无法创建“System.Object”类型的常量值。此上下文仅支持基元类型或枚举类型

无法创建“匿名类型”类型的常量值。此上下文仅支持基元类型或枚举类型。

LINQ 查询以从分组中查找最小值 - 无法创建类型为“X”的常量

DbContext.set() 无法为实体创建 DbSet,因为此类型未包含在上下文的模型中