I'm working on building a repository system on top of a system that is a bit harder to work on than usual (ref. a previous question by me).
Anyway.
My data model is fairly simple at this point: I have several countries, and each country has 0 or more airports. Here's my base Repository:
public abstract class Repository<T> : IRepository<T> where T : Entity, new()
{
protected SimpleSQLManager SQLManager = DatabaseManager.Instance.SQLManager;
public virtual IQueryable<T> GetAll()
{
IQueryable<T> all = SQLManager.Table<T>().AsQueryable();
return all;
}
public virtual IQueryable<T> GetAll(Expression<Func<T, bool>> predicate)
{
IQueryable<T> all = SQLManager.Table<T>().Where(predicate).AsQueryable();
return all;
}
public T GetById(string tableName, int id)
{
return SQLManager.Query<T>( "SELECT * FROM " + tableName + " WHERE Id = ?", id )[0];
}
}
Please ignore the ugly GetById()
implementation; I'm running this on Unity3D's (Mono's) .NET libraries, and there's seemingly a bug in there which makes it impossible at the moment to do it properly. Either way, that's not the problem. :)
Now, a normal EntityRepository looks like this (CountryRepository in this case):
public class CountryRepository : Repository<Country>
{
public override IQueryable<Country> GetAll()
{
return base.GetAll().OrderBy( c => c.Name );
}
public Country GetById(int id)
{
return base.GetById( "Country", id );
}
}
The Country entity looks like this:
public class Country : Entity
{
public IQueryable<Airport> Airports()
{
return RepositoryFactory.AirportRepository.GetByCountry( this );
}
}
Then, in my application I can do something like this:
foreach ( Country c in RepositoryFactory.CountryRepository.GetAll() )
{
foreach ( Airport a in c.Airports() )
{
// ...
}
}
...and this works just fine; I'm happy with how everything is abstracted away etc. etc. :)
The problem is that the above code creates one database SELECT per country, which is highly ineffective. This is where I'm not sure where to go forward. I know how to do this with plain old SQL, but I want to go the Linq (or otherwise "non-SQL") way.
Can someone point me in the right/correct direction?
Thanks!
Aucun commentaire:
Enregistrer un commentaire