在过去的6个月中,我一直在使用EF 3.5与这一限制作斗争,尽管我不是世界上最聪明的人,但是我敢肯定,在这个问题上我可以提供一些有用的东西。
通过生长50英里高的“ OR风格”表达式树生成的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列名称。
但是请保持阅读!
很好,但是它要求我已经具有需要查找的ID。有时候,我只是想表达自己的观点,以达到其他关系,而我所拥有的就是这些联系关系的标准。
如果我有更多的时间,我会尝试用视觉来表示它,但是我不那么研究这一句话:考虑一个具有Person,GovernmentId和GovernmentIdType表的模式。安德鲁·塔珀特(人)有两张身份证(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将使用“ joins”而不是子查询,但是效果是相同的。如今,无论如何,SQL Server都会将子查询优化为隐藏的联接,但是无论如何...
这项工作的关键是表达式中的.Any。