在此上下文中只支持基本类型或枚举类型

本文关键字:类型 枚举 支持 上下文 | 更新日期: 2023-09-27 18:02:05

我已经看到了很多关于这个主题的问题,但是我还没有能够通过他们中的任何一个来真正解决我所看到的问题。我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建并更新了记录。如果我删除' where a.AssignedEmployee == currentUser'行代码,我不会得到下面的运行时错误。

无法创建类型为"datmodels . employee"的常数值。只有在此上下文中支持基本类型或枚举类型。

h2控制器

var query = from a in db.Activities
            where a.AssignedEmployee == currentUser
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());
<<h2>视图/h2>
@model IEnumerable<Data.DataModels.Activity>
..........

在此上下文中只支持基本类型或枚举类型

我的猜测是,错误表明EF无法将Employee的相等运算符转换为SQL(无论您是假设引用相等还是覆盖==运算符)。假设Employee类有唯一标识符,try:

var query = from a in db.Activities
            where a.AssignedEmployeeId == currentUser.Id
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());

它不喜欢您试图将整个对象相等转换为数据库查询的事实。您只能使用常量值执行实体框架查询,就像执行SQL查询一样。解决这个问题的方法是比较这些ID,看看assigneemployee的ID是否与employee表中当前用户的ID相同。

作为旁注,如果您正在跟踪的currentUser对象不是Employee类型,您可能需要考虑缓存该用户的相应Employee记录,以便在以后的查询中更好地引用它。这比不停地遍历那个表要好得多。(同样,这只会影响你,如果它实际上是在一个不同的表)

使用==和obj的问题。Equals是实体框架不知道如何把那个方法调用转换成SQL——即使你把那两个方法重载成可以转换成SQL的东西。要在实体框架中修复这个缺点,你可以创建一个返回表达式树的方法,该表达式树可以完成你想要做的更复杂的相等性检查。

例如,假设我们有以下类

public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}

为了返回一个实体框架能够理解的自定义相等操作,在Person类中添加以下方法:

public static Expression<Func<Person, bool>> EqualsExpressionTree(  Person rhs )
{
    return ( lhs ) => string.Equals( lhs.Firstname, rhs.Firstname ) &&
                      string.Equals( lhs.Lastname, rhs.Lastname );
}

在你的LINQ查询中,你可以像这样利用你的自定义等式代码:

Person anotherPerson = new Person { Firstname = "John", Lastname = "Doe" }
personCont.Where( Person.EqualsExpressionTree(anotherPerson) );
//...
if ( personCont.Any( Person.EqualsExpressionTree(anotherPerson)) ) {
//...

此外,可以重写EqualsExpressionTree方法以调用静态Equals方法,从而允许您利用自定义的相等逻辑。然而,无论如何,记住你的代码必须转换成SQL表达式,因为我们毕竟是在调用数据库,而不是从内存访问东西。