我已经看到很多关于这个主题的问题,但是我无法解决任何真正解决我所看到的问题的问题。我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建了记录并对其进行了更新。如果我删除`where a.AssignedEmployee == currentUser'代码行,我不会在下面得到运行时错误。
无法创建“DataModels.Employee”类型的常量值。只要 在此上下文中支持原始类型或枚举类型。
var query = from a in db.Activities
where a.AssignedEmployee == currentUser
where a.IsComplete == false
orderby a.DueDate
select a;
return View(query.ToList());
@model IEnumerable<Data.DataModels.Activity>
..........
答案 0 :(得分:60)
我的猜测是错误表明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());
答案 1 :(得分:7)
它不喜欢您尝试将整个对象相等性转换为数据库查询的事实。您只能使用常量值进行实体框架查询,就像您进行SQL查询一样。解决这个问题的方法是比较ID,看看AssignedEmployee的ID是否与employee表中当前用户的ID相同。
作为旁注,如果您跟踪的currentUser
对象不属于Employee类型,您可能需要考虑缓存该用户的相应Employee记录,以便以后更好地引用它查询。这比试图不断地通过那张桌子要好得多。 (如果它实际上在另一个表中,这只会影响你)
答案 2 :(得分:4)
使用==和obj.Equals的问题是Entity Framework不知道如何将该方法调用转换为SQL--即使您将这两个方法重载为可转换为SQL的方法。您可以采取哪些措施来解决Entity Framework中的这个缺点,即创建一个返回表达式树的方法,该表单树执行您希望执行的更复杂的相等性检查。
例如,假设我们有以下类
public class Person {
public string Firstname { get; set; }
public string Lastname { get; set; }
}
为了返回Entity Framework可以理解的自定义相等操作,将以下方法添加到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表达式,因为我们毕竟是调用数据库而不是从内存中访问内容。