I have a number of LINQ classes that inherit from the same base class. Each Linq class has its own table, and then the base class is a sort of link to another table. I’ll try and illustrate the relationship:
//Base Class
abstract class Element<T>
{
public string Name {get; set;}
public string Species {get; set;}
}
public partial class DogElement : Element<DogElement>
{
public int Legs {get; set;}
public bool hasHair {get; set;}
}
public partial class CatElement : Element<CatElement>
{
public bool hasWiskers {get; set}
}
So DogElement and CatElement are separate physical tables in the database. The Species class will read from the Species table. I basically want to have a generic function in Element that groups the T table with the Species table and returns the result as a T after having set .Species.
//Assume T is DogElement for this example
public IQueryable<T> Collection
{
using (DataBase db = new DataBase())
{
var k = from t in db.GetTable<T>()
where t.SomeID == SomeOtherID
select t;
k = { {Legs = 4, HasHair = True, Species = <null>, Name = <null>}, ...}
I basically want a query that will return an IQueryable<DogElement> with Name
and Species set from a join query. What is the best way to set the Name and
Species values?
return k;
}
Essentially you are asking SQL to handle inheritance (it doesn’t do that)… and LINQ doesn’t model inheritance either. A good object relational mapper (ORM) will help you piece something together more generically.
That said, here’s a quick discussion.
First off, I think it is better to write one LINQ query for each species-animal pair.
You could write a union, switch in the LINQ select, create a new animal, and then cast that animal to a species in one go… then outside the LINQ statement, recast it to T on the way out. This kind of statement sounds messy though.
Although this is less efficient than one big union statement, have you considered this more maintainable option?
that’s two trips to the database (slower), but it’s more maintainable, and often it is better not to over optimise your code on the first pass.