Lets say i have an Animal
class which has some descendants that derive from it like Dog
Cat
and Mouse
public class Animal{}
public class Dog : Animal {}
public class Cat : Animal {}
public class Mouse: Animal {}
Now lets say entities of those objects are stored in sql database and that i use Entity Framework for communication with that database. Dogs, cats and mouses are all stored in different tables, but in code they share the same parent from which they derive.
If i want to get all animals that fulfill the same expression i would have to query each DbSet separately and give it the same expression but with different type of parameter, so a cat gets a cat parameter type and a dog gets a dog parameter like this
var cats = context.Cats.Where(p=>some expression);
var dogs= context.Dogs.Where(p=>some expression);
var mice= context.Mice.Where(p=>some expression);
var animals = new List<Animal>();
animals.AddRange(cats);
animals.AddRange(dogs);
animals.AddRange(mice);
But, this poses a problem to me, because if i ever wanted to add another animal type for example Bird
i would have to add another line of code that gets the data from database and adds it to the result collection. This behaviour is badly managable and i would want for it to loop through types that derive from Animal
and programaticaly construct an expression for proper type based on provided source expression which is passed as a parameter to method as a Animal
type expression. Something like this:
public List<Animal> GetAnimals(Expression<Func<Animal, bool>> expression)
{
var animalTypes = GetTypesDerivingFrom(typeof(Animal));
List<Animal> animals = new List<Animal>();
foreach(var animalType in animalTypes)
{
var typeTranslatedExpression = GetTypeTranslatedExpression(expression); //i dont know how to do this part
var portionOfAnimals = context.Set(animalType).Where(typeTranslatedExpression).ToList();
animals.AddRange(portionOfAnimals);
}
return animals;
}
Is there any way to do this? I thought about changing the expression parameter type but i cant seem to figure it out without knowing the proper parameter type at code time.