41

我已经看到了很多关于这个主题的问题,但是我无法对其中任何一个真正解决我所看到的问题的问题进行分类。我有一个活动实体,它跟踪分配给哪个员工以及哪个员工创建并更新了记录。如果我删除 `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>
..........
4

3 回答 3

65

我的猜测是该错误表明 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());
于 2013-03-04T21:24:14.630 回答
8

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

附带说明一下,如果currentUser您正在跟踪的对象不是 Employee 类型,您可能需要考虑缓存该用户的相应 Employee 记录,以便在以后的查询中更好地引用它。这比试图不断地通过那张桌子要好得多。(同样,这只会影响您,如果它实际上是在不同的表中)

于 2013-03-04T21:24:42.067 回答
5

使用 == 和 obj.Equals 的问题是实体框架不知道如何将该方法调用转换为 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 表达式,因为毕竟我们是在调用数据库而不是从内存中访问内容。

于 2014-05-30T05:31:52.673 回答