我环顾四周但找不到可靠的答案。我已经考虑了一段时间了,我真的想不出一个好的解决方案。
假设我有5个IEnumerable,它们都可以为空,所以它们可能是空的。
IEnumerable<Genus> Genera
IEnumerable<string> SpeciesIds (list of keys)
IEnumerable<string> EnvrionmentIds (list of keys)
IEnumerable<string> SpeciesIds_Exclusion (list of keys)
IEnumerable<string> EnvironmentIds_Exclusion (list of keys)
Genus是一个具有Id,name,SpeciesId和EnvionmentId的对象。
现在要理解这一点,以下是这些枚举如何分组的示例:
每个IEnumerable都是在Genera IEnumerable中找到的键(或id)的枚举。
现在,我希望能够基于此创建场景;在那里我可以获得所有动物的清单,或某些物种的所有动物的过滤清单,特定环境的所有动物的清单,除某些物种之外的所有动物的清单,以及每种环境中所有动物的清单,排除某些环境。
我有两种解决方案。要么1,要执行一系列左连接,Genera,SepeciesIds,EnvironmentIds,并将SpeciesIds_SubExclusion和EnvironmentIds_Exclusion放在where子句中。但是我认为在没有必要的情况下查询会太昂贵,比如我想要一个所有Genera的列表而不管EnvironmentIds或SpeciesIds,为什么我会在这两个上加入?
所以我想出了一个使用if语句的解决方案,并且想知道这是否是更好的优化方式:
query是一个包含我提到的所有IEnumebles的对象:
var GenusQuery = query.Genera;
//the join filters down to give back the genus of animals found in the species list
if (query.SpeciesIds != null && query.SpeciesIds.Any())
{
GenusQuery = (from genus in GenusQuery
join species in query.SpeciesIds
on genus.speciesId equals species
select new {
id = genus.id,
name = genus.name,
environmentId = genus.environmentId
speciesId = genus.speciesId
});
}
if (query.EnvironmentIds != null && query.EnvironmentIds.Any())
{
GenusQuery = (from genus in GenusQuery
join environment in query.EnvironmentIds
on genus.environmentId equals environment
select new {
id = genus.id,
name = genus.name,
environmentId = genus.environmentId
speciesId = genus.speciesId
});
}
//I think the below fails, I haven't tested it out
if (query.SpeciesIds_Exclusion != null && query.SpeciesIds_Exclusion.Any())
{
GenusQuery = GenusQuery.Except(x => query.SpeciesIds_Exclusion(x.speciesId));
}
if (query.EnvironmentIds_Exclusion != null && query.EnvironmentIds_Exclusion.Any())
{
GenusQuery = GenusQuery.Except(x => query.EnvironmentIds_Exclusion.Contains(x.environmentIds));
}
有没有人对上述解决方案有任何更好的建议,或者这是建议的做一系列条件ifs以确定查询的最终结果的做法?我有点担心这个问题,因为如果我在这个查询中添加更多的IEnumerables会包含更多的条件ifs,因为这个函数会继续增长并成长为代码的整体。
答案 0 :(得分:1)
我认为以下方法应该非常有效:
// check if your collections are null
var SpeciesIds = query.SpeciesIds ?? new List<string>();
var SpeciesIds_Exclusion = query.SpeciesIds_Exclusion ?? new List<string>();
var EnvironmentIds = query.EnvironmentIds ?? new List<string>();
var EnvironmentIds_Exclusion = query.EnvironmentIds_Exclusion ?? new List<string>();
// do the query
var GenusQuery = query.Genera
.Where(x => SpeciesIds.Contains(x.speciesId) &&
!SpeciesIds_Exclusion.Contains(x.speciesId))
.Where(x => EnvironmentIds.Contains(x.environmentId) &&
!EnvironmentIds_Exclusion.Contains(x.environmentId))
.ToList();
在where where子句中,需要具有正确id且未排除id的数据。在这种情况下,您的联接不是必需的,但如果您需要它们,则不应创建结果对象的新实例:
GenusQuery = (from genus in GenusQuery
join environment in query.EnvironmentIds
on genus.environmentId equals environment
select genus); // not new instance, but looping variable here