【发布时间】:2015-10-05 12:58:19
【问题描述】:
我有一个方法可以接受两个List<int>,为此我需要根据List<>s 从数据库中获取数据。
因此,例如,我收到了 List<PersonId> 和 List<NationalityId>,我需要获取记录与 PersonIds 和 NationalistIds 匹配的结果集。
public List<PersonDTO> SearchPeople(List<int> persons, Lisy<int> nationalities)
{
var results = (from c in myDbContect.People where .... select c).ToList();
}
请注意,我认为 Lists 可能为空。
有没有有效的方法? 我打算试试:
where ((persons != null && persons.Count > 0) && persons persons.Contains(x=>x.PersonId))
但这会产生相当低效的 SQL,而且当我添加更多搜索参数时,linq 可能会变得非常混乱。
有没有一种有效的方法来实现这一点?
join 方法可能很容易阅读,但我面临的问题是如果输入列表为空,那么它不应该过滤。也就是说,如果国籍为空,则不要过滤掉:
var results = (from c in entities.Persons
join p in persons on c.PersonId equals b
join n in nationalities on c.NationalityId equals n
等于 n 选择 c).ToList();
如果任何列表为空,这将不返回任何结果。哪个不好。
【问题讨论】:
-
"但这会产生相当低效的 SQL" - 你怎么知道的?过滤最好在数据库中完成.....
-
@MitchWheat,虽然你说的是真的,但在这种特殊情况下,如果列表包含超过 2000 个组合的项目,则生成的查询将根本无法执行 - 中的所有值每个列表都被转换为一个参数,并且 sql 查询对参数数量有限制。
-
sql 查询中的最大参数数为 2100。在单个参数中传入 CSV 值列表(并使用表值拆分函数将这些值转换为行),或使用表值参数将比处理所有这些输入参数容易得多。
-
加入列表
似乎是有效的,假设连接会生成内部连接?如果是这样,我该如何做到这一点,如果列表为空或 null,则必须返回所有值?