我正在建立一个系统之上的存储库系统,这个系统比平常更难处理(参考previous question by me)。
反正。
我的数据模型在这一点上相当简单:我有几个国家,每个国家都有0个或更多机场。这是我的基础知识库:
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];
}
}
请忽略丑陋的GetById()
实施;我在Unity3D的(Mono的).NET库上运行它,并且在那里看似a bug,这使得目前无法正确地执行它。无论哪种方式,这不是问题。 :)
现在,正常的EntityRepository看起来像这样(在本例中为CountryRepository):
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 );
}
}
国家/地区实体如下所示:
public class Country : Entity
{
public IQueryable<Airport> Airports()
{
return RepositoryFactory.AirportRepository.GetByCountry( this );
}
}
然后,在我的应用程序中,我可以做这样的事情:
foreach ( Country c in RepositoryFactory.CountryRepository.GetAll() )
{
foreach ( Airport a in c.Airports() )
{
// ...
}
}
......这很好用;我很高兴一切都被抽象出来等等。)
问题是上述代码为每个国家/地区创建一个数据库SELECT,这是非常无效的。这是我不知道在哪里前进的地方。我知道如何使用普通的旧SQL执行此操作,但我想使用Linq(或其他“非SQL”)方式。
有人能指出我正确/正确的方向吗?
谢谢!
答案 0 :(得分:2)
我在SimpleSQL的文档中看不到任何东西,看起来它会让sql lite生成一个连接 - 类似于实体框架的Include
方法。
也就是说,您可以通过2个查询将所有机场和国家带入内存并手动将它们相互挂钩,如下所示:
var airports = RepositoryFactory.AirportRepository.GetAll().ToList();
var countries = RepositoryFactory.CountryRepository.GetAll().ToList();
countries.ForEach(c => c.Airports = airports.Where(a => a.CountryId == c.Id));
请注意,您需要向国家/地区类添加属性:
public IEnumerable<Airport> Airports {get;set;}
我不喜欢它,但这可能是给你环境的唯一方式。您可以使用泛型进一步抽象连接/映射逻辑,但这是基本思想。