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

C# 在此上下文中仅支持基元类型或枚举类型,c#,asp.net-mvc,linq,entity-framework,C#,Asp.net Mvc,Linq,Entity Framework,我已经看到了很多关于这个话题的问题,但我还没能整理出任何能真正解决我所看到的问题的问题。我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建并更新了记录。如果删除“where a.AssignedEmployee==currentUser”代码行,则不会出现下面的运行时错误 无法创建“DataModels.Employee”类型的常量值。只有 在此上下文中支持基元类型或枚举类型 控制器 看法 @model IEnumerable .......... 我的猜测是,错误表明EF无法将Employ

我已经看到了很多关于这个话题的问题,但我还没能整理出任何能真正解决我所看到的问题的问题。我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建并更新了记录。如果删除“where a.AssignedEmployee==currentUser”代码行,则不会出现下面的运行时错误

无法创建“DataModels.Employee”类型的常量值。只有 在此上下文中支持基元类型或枚举类型

控制器 看法
@model IEnumerable
..........

我的猜测是,错误表明EF无法将
Employee
的相等运算符转换为SQL(无论您假设的是引用相等还是重写的
=
运算符)。假设
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());

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


作为一个旁注,如果您跟踪的CurruthUs>/Cux>对象不属于雇员类型,您可能需要考虑缓存该用户的相应雇员记录,以便更好地在以后的查询中引用它。这比试着不停地检查那张桌子要好得多。(同样,这只会影响您,如果它实际上位于不同的表中)

使用==和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 );
}

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

在这种情况下,
==
是否执行引用相等?注意:询问ref是否相等supported@JaredPar你说得对。。。白痴奖颁给了我。我尝试了18种不同的方法来编写这个查询,但由于某种原因,在该对象上使用ID属性并不是其中之一。我会把这归咎于今天缺少星巴克。咖啡是你的朋友;)那太糟糕了。。。如果在NHibernate中有一个Id可以正常工作。。。我知道添加。Id不是很糟糕,但是没有。Id更优雅。。。
public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}
public static Expression<Func<Person, bool>> EqualsExpressionTree(  Person rhs )
{
    return ( lhs ) => string.Equals( lhs.Firstname, rhs.Firstname ) &&
                      string.Equals( lhs.Lastname, rhs.Lastname );
}
Person anotherPerson = new Person { Firstname = "John", Lastname = "Doe" }
personCont.Where( Person.EqualsExpressionTree(anotherPerson) );
//...
if ( personCont.Any( Person.EqualsExpressionTree(anotherPerson)) ) {
//...