繁体   English   中英

存储库模式和组合/联接的实体作为优化的SQL

[英]Repository pattern and combined/joined entities as optimised SQL

我正在构建一个比通常更难工作的系统之上的存储库系统(请参阅我之前的问题 )。

无论如何。

此时,我的数据模型非常简单:我有几个国家,每个国家都有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库上运行此程序,并且其中似乎存在一个错误 ,导致目前无法正确执行此操作。 无论哪种方式,这都不是问题。 :)

现在,一个普通的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”)方式。

有人可以指出我正确/正确的方向吗?

谢谢!

我没有在SimpleSQL的文档中看到任何看起来像会使sql lite生成联接的东西-类似于实体框架的Include方法。

就是说,您可以通过两个查询将所有机场和国家/地区带入内存,然后手动将它们彼此挂钩,如下所示:

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;}

我不喜欢它,但这可能是您所处环境的唯一方法。 您可以使用泛型进一步抽象联接/映射逻辑,但这是基本思想。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM