在此上下文中仅支持基元类型或枚举类型

RSo*_*erg 38 c# linq asp.net-mvc entity-framework

我已经看到很多关于这个主题的问题,但是我无法解决任何实际解决我所看到的问题的问题.我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建了记录并对其进行了更新.如果我删除`where a.AssignedEmployee == currentUser'代码行,我不会得到下面的运行时错误.

无法创建"DataModels.Employee"类型的常量值.在此上下文中仅支持基元类型或枚举类型.

CONTROLLER

var query = from a in db.Activities
            where a.AssignedEmployee == currentUser
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());
Run Code Online (Sandbox Code Playgroud)

视图

@model IEnumerable<Data.DataModels.Activity>
..........
Run Code Online (Sandbox Code Playgroud)

D S*_*ley 64

我的猜测是错误表明EF无法将等于运算符转换为EmployeeSQL(无论您是假设引用相等还是重写==运算符).假设Employee该类具有唯一标识符,请尝试:

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());
Run Code Online (Sandbox Code Playgroud)


Iro*_*n84 8

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

作为旁注,如果currentUser您跟踪的对象不属于Employee类型,您可能需要考虑缓存该用户的相应Employee记录,以便能够在以后的查询中引用它.这比试图不断地通过那张桌子要好得多.(同样,这只会影响你,实际上,它在另一个表中)


rmi*_*sen 5

使用==和obj.Equals的问题在于,即使将这两个方法重载为可转换为SQL的对象,Entity Framework也不知道如何将该方法调用转换为SQL。要纠正Entity Framework中的这一缺陷,您可以做的是创建一个方法,该方法返回一个表达式树,该树执行您要执行的更复杂的相等性检查。

例如,假设我们有以下课程

public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

为了返回实体框架可以理解的自定义相等操作,请向Person类添加以下方法:

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

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

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

此外,可以重写EqualsExpressionTree方法以调用静态Equals方法,从而使您能够利用自定义的相等逻辑。但是,在所有情况下,请记住,您的代码必须转换为SQL表达式,因为我们毕竟是在调用数据库,而不是从内存访问内容。