在过去的 6 个月中,我一直在与 EF 3.5 的这个限制作斗争,虽然我不是世界上最聪明的人,但我很确定我可以在这个主题上提供一些有用的东西。
通过增长 50 英里高的“OR 样式”表达式树生成的 SQL 将导致糟糕的查询执行计划。我正在处理几百万行,并且影响很大。
如果您只是通过 id 查找一堆实体,我发现有一个小技巧可以帮助您执行 SQL 'in':
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 表的架构。 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会使用'joins'而不是子查询,但是效果是一样的。这些天来,SQL Server 无论如何都将子查询优化为连接,但无论如何......
这项工作的关键是表达式中的 .Any。