實現倉儲


返回總目錄《一步一步使用ABP框架搭建正式項目系列教程》


這一節我們來實現上一節定義的倉儲接口。

上一節是在領域層定義的倉儲接口,但是需要注意的是,實現這些倉儲接口是在基礎設施層,在我的項目中就是EntityFramework層。這樣做的好處就是領域層完全獨立於基礎設施層,耦合程度大大降低。

上一節我們定義了一個ICityRepository倉儲接口,所以接下來我們來實現它。現在我們找到基礎設施層名為“Repositories”的文件夾,在這里面存放實現倉儲接口的類。這個文件夾是ABP模板自動幫我們生成的,而且可以它看到還有一個父目錄EntityFramework。本目錄下ABP模板已經幫我們創建了一個倉儲基類“ChargeStationRepositoryBase”,以后如果我們要給倉儲實現添加公共的方法時,就可以直接添加到該基類中。父目錄下有一個之前講過的數據庫上下文類的子類。

image

接下來,在Repositories文件夾里定義ICityRepository的實現類CityRepository,代碼如下:

namespace Noah.ChargeStation.EntityFramework.Repositories
{
    public class CityRepository:ChargeStationRepositoryBase<Cities>,ICityRepository
    {
        public CityRepository(IDbContextProvider<ChargeStationDbContext> dbContextProvider):base(dbContextProvider)
        {
            
        }
        public List<Cities> GetCitiesWithProvince(string provinceCode)
        {
            var query = GetAll();//GetAll()返回一個IQueryable<T>,我們可以通過它來查詢
              var query2 = Context.Cities.AsQueryable();//也可以直接使用EF的DbContext對象
              var query3 = Table.AsQueryable();//另一種選擇:直接使用Table屬性代替"Context.Cities",都是一樣的。
              if (!string.IsNullOrEmpty(provinceCode))
            {
                query = query.Where(c => c.ProvinceCode == provinceCode);
            }
            return query.ToList();
        }
    }
}

CityRepository繼承了泛型的ChargeStationRepositoryBase類,而且實現了倉儲接口。這里要顯示聲明實現類的有參數的構造函數,使用泛型的IDbContextProvider將數據庫上下文的子類ChargeStationContext傳給父類的構造函數。

GetCitiesWithProvince(…)方法是我們實現倉儲接口ICityRepository中的方法,也是我們自己特殊需要的方法。

在倉儲中,我們可以自由地使用Context(EF的DbContext)對象和數據庫。ABP框架為我們管理數據庫連接,事務,創建和釋放DbContext,因而不用我們自己處理了。

這里我們也可以定義一個異步版本的方法,功能和上面的方法相同(關於異步的博客,可以看我的目錄《C#異步編程》):

        public async Task<List<Cities>> GetCitiesWithProvinceAsync(string provinceCode)
        {
            return await GetAllListAsync(c => c.ProvinceCode == provinceCode);
        }

這里注意一下GetAll()方法和GetAllList()方法的區別:前者返回的類型是IQueryable<T>,后者是List<T>。說到這里又不得不說下IQueryable<T>和List<T>的區別。

IQueryable<T>:

當你在Repository對象以外的地方調用GetAll這個方法,必定會開啟數據庫連接。這是因為IQueryable<T>允許延遲執行。只有在IQueryable<T>(或一些存取已查詢的對象方法)上使用ToList()或foreach()迭代IQueryable<T>時,才會實際執行數據庫的查詢。因此,當你調用ToList方法時,數據庫連接必需是啟用狀態。我們可以使用ABP所提供的UnitOfWork特性在調用的方法上來實現。注意,Application Service方法預設都已經是UnitOfWork。因此,使用了GetAll方法就不需要如同Application Service的方法上添加UnitOfWork特性。

List<T>:

返回的該結果說明已經執行了數據庫查詢或者已經從內存中取出了數據(如果內存中有的話)。

好的,今天的實現倉儲就講到這,下一次說《構建應用層服務》。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM