实体框架 - “无法创建类型'闭包类型'的常量值...”错误

entity-framework linq

为什么我会收到错误:

无法创建“闭包类型”类型的常量值。在此上下文中仅支持基本类型(例如Int32,String和Guid)。

当我尝试枚举以下Linq查询?

IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
   var myList = from person in entities.vSearchPeople
   where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}

更新 :如果我尝试以下尝试隔离问题,我得到相同的错误:

where upperSearchList.All(arg => arg == arg) 

所以看起来问题出在All方法上,对吧?有什么建议?

一般承认的答案

看起来你正试图做相当于“WHERE ... IN”的条件。查看如何使用LINQ to Entities编写'WHERE IN'样式查询,以获取如何使用LINQ to Entities进行该类型查询的示例。

此外,我认为错误消息在这种情况下特别无用,因为.Contains后面没有括号,这会导致编译器将整个谓词识别为lambda表达式。


热门答案

过去6个月我一直在与EF 3.5争夺这个限制,虽然我不是世界上最聪明的人,但我很确定我在这个主题上有一些有用的东西。

通过增长50英里高的“OR style”表达式生成的SQL将导致查询执行计划不佳。我正在处理几百万行,影响很大。

我发现做一个SQL'in'有点麻烦,如果你只是通过id寻找一堆实体,这会有所帮助:

private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
    string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
    return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}

其中pkIDColumn是Entity1表的主键id列名。

但继续阅读!

这很好,但它要求我已经拥有了我需要找到的东西。有时我只是希望我的表达能够与其他关系联系起来,而我所拥有的是那些相关关系的标准。

如果我有更多的时间,我会尝试直观地表示这一点,但我不会那么只研究这句话:考虑一个带有Person,GovernmentId和GovernmentIdType表的模式。 Andrew Tappert(人)有两张身份证(GovernmentId),一张来自俄勒冈州(GovernmentIdType),一张来自华盛顿(GovernmentIdType)。

现在从中生成一个edmx。

现在假设你想要找到所有具有特定ID值的人,比如1234567。

这可以使用以下单个数据库命中来完成:

dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
    person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));

IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);

你看到子查询了吗?生成的sql将使用'join'而不是子查询,但效果是相同的。这些天SQL服务器无论如何都将子查询优化为连接下的连接,但无论如何......

这项工作的关键是表达式中的.Any。



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因