I've looked around but couldn't find a solid answer. I've been thinking about this for a while, and I couldn't really think up of a good solution for this.
Let say I have 5 IEnumerable, they are all nullable, so they could be empty.
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 is an object that has an Id, name, SpeciesId, and EnvionmentId.
Now to make sense of this, here's an example of how these enumerations are grouped:
Each IEnumerable an enumeration of keys (or ids) that are found in the Genera IEnumerable.
Now, I want to be able to create scenarios based on this; where I can get a list of all animals, or a filtered list of all animals of certain species, a list of all animals of a specific environment, a list of all animals excluding certain species, and a list of all animals in every environment but excluding certain environments.
I had 2 solutions of going about this. Either 1, do a series of left joins, Genera, SepeciesIds, EnvironmentIds, and put the SpeciesIds_SubExclusion and EnvironmentIds_Exclusion in a where clause. But I was thinking that this would be too expensive of a query when not necessary, like if I wanted a list of all Genera regardless of EnvironmentIds or SpeciesIds, why would I do a join on those two?
So I came up with a solution of using if statements, and was wondering if this is the better optimized way of proceeding about this:
query is an object that contains all the IEnumerables I mentioned:
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));
}
Does anyone have any better suggestions to the above solution or is this a recommended practice of doing a series of conditional ifs to determine the final outcome of the query? I'm kind of concerned about this because more conditional ifs would be included if I add more IEnumerables on this query, as this function would keep on growing and growing into a monolith of code.