Gus*_*nti 79 linq entity-framework
为什么我会收到错误:
无法创建"闭包类型"类型的常量值.在此上下文中仅支持基本类型(例如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();
}
Run Code Online (Sandbox Code Playgroud)
更新:如果我尝试以下尝试隔离问题,我得到相同的错误:
where upperSearchList.All(arg => arg == arg)
Run Code Online (Sandbox Code Playgroud)
所以看起来问题出在All方法上,对吧?有什么建议?
Dan*_*att 68
看起来你正试图做相当于"WHERE ... IN"的条件.查看如何使用LINQ to Entities编写'WHERE IN'样式查询,以获取如何使用LINQ to Entities进行该类型查询的示例.
此外,我认为错误消息在这种情况下特别无用,因为.Contains后面没有括号,这会导致编译器将整个谓词识别为lambda表达式.
and*_*rew 11
过去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 + "}");
}
Run Code Online (Sandbox Code Playgroud)
其中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);
Run Code Online (Sandbox Code Playgroud)
你看到子查询了吗?生成的sql将使用'join'而不是子查询,但效果是相同的.这些天SQL服务器无论如何都将子查询优化为连接下的连接,但无论如何......
这项工作的关键是表达式中的.Any.
我找到了错误的原因(我正在使用Framework 4.5).问题是,EF是一个复杂类型,它在"包含"参数中传递,不能转换为SQL查询.EF只能在SQL查询中使用简单类型,如int,string ......
this.GetAll().Where(p => !assignedFunctions.Contains(p))
Run Code Online (Sandbox Code Playgroud)
GetAll提供具有复杂类型的对象列表(例如:"Function").所以,我会在这里尝试在我的SQL查询中接收这个复杂类型的实例,这自然是行不通的!
如果我可以从我的列表中提取适合我搜索的参数,我可以使用:
var idList = assignedFunctions.Select(f => f.FunctionId);
this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Run Code Online (Sandbox Code Playgroud)
现在EF不再具有复杂类型"功能",但是例如使用简单类型(长).这很好!