日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ABP理论学习之仓储

發布時間:2025/3/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ABP理论学习之仓储 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇目錄

  • IRepository接口
    • 查詢
    • 插入
    • 更新
    • 刪除
    • 其他
    • 關于異步方法
  • 倉儲實現
  • 管理數據庫連接
  • 倉儲的生命周期
  • 倉儲最佳實踐

Martin Fowler對倉儲的定義

位于領域層和數據映射層之間,使用類似集合的接口來訪問領域對象。

在實踐中,倉儲是執行領域對象(實體和值對象)的數據庫操作。一般地,一個分離的倉儲用于一個實體(或者聚合根)。

IRepository接口

在ABP中,一個倉儲類應該實現一個IRepository接口。為每一個倉儲定義一個接口是一個好的做法。

一個Person實體的倉儲定義如下:

public interface IPersonRepository : IRepository<Person> { }

IPersonRepository擴展了IRepository,它用于定義擁有主鍵類型為int32的實體。如果你的實體不是int,那么可以擴展IRepository,tprimarykey>接口,如下所示:

public interface IPersonRepository : IRepository<Person, long> { }

IRepository為倉儲類定義了最通用的方法,如select,insert,update和delete方法(CRUD操作)。大多數情況下,這些方法對于簡單的實體是足夠了。如果這些方法對于一個實體來說已經足夠了,那么就沒有必要為這個實體創建倉儲接口和倉儲類了。看下面。

查詢

IRepository定義了通用的方法,從數據庫中檢索實體。

獲得單個實體
TEntity Get(TPrimaryKey id); Task<TEntity> GetAsync(TPrimaryKey id); TEntity Single(Expression<Func<TEntity, bool>> predicate); Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate); TEntity FirstOrDefault(TPrimaryKey id); Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id); TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate); Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate); TEntity Load(TPrimaryKey id);

Get方法用于獲得一個給定主鍵(Id)的實體。如果在數據庫中沒有找到這個實體,就會拋出異常。Single方法和Get類似,但是它的參數是一個表達式而不是一個Id。因此,你可以使用Lambda表達式獲得一個實體。樣例用法:

var person = _personRepository.Get(42); var person = _personRepository.Single(p => p.Name == "Halil ?brahim Kalkan");

注意:如果根據給定的條件沒有查找出實體或者查出不止一個實體,那么Single方法會拋出異常。

FirstOrDefault是相似的,但是如果根據給的的Id或者表達式沒有找到實體,那么就會返回null。如果對于給定的條件存在不止一個實體,那么會返回找到的第一個實體。

Load方法不會從數據庫中檢索實體,但是會創建一個用于懶加載的代理對象。如果你只用了Id屬性,那么Entity實際上并沒有檢索到。只有你訪問實體的其他屬性,才會從數據庫中檢索。考慮到性能因素,這個就可以替換Get方法。這在NHiberbate中也實現了。如果ORM提供者沒有實現它,那么Load方法會和Get方法一樣地工作。

一些方法有用于async編程模型的異步(async)版本。

獲得實體的列表

List<TEntity> GetAllList(); Task<List<TEntity>> GetAllListAsync(); List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate); Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate); IQueryable<TEntity> GetAll();

GetAllList從數據庫中檢索所有的實體。該方法的重載可以用于過濾實體。例子如下:

var allPeople = _personRepository.GetAllList(); var somePeople = _personRepository.GetAllList(person => person.IsActive && person.Age > 42);

GetAll返回的類型是IQueryable。因此,你可以在此方法之后添加Linq方法。例子如下:

//Example 1 var query = from person in _personRepository.GetAll()where person.IsActiveorderby person.Nameselect person; var people = query.ToList();//Example 2: List<Person> personList2 = _personRepository.GetAll().Where(p => p.Name.Contains("H")).OrderBy(p => p.Name).Skip(40).Take(20).ToList();

有了GetAll方法,幾乎所有的查詢都可以使用Linq重寫。甚至可以用在一個連接表達式中。

關于IQueryable

脫離了倉儲方法調用GetAll()方法時,數據庫連接必須要打開。這是因為IQueryable的延遲執行。直到調用ToList()方法或者在foreach循環中使用IQueryable(或者訪問查詢到的元素)時,才會執行數據庫查詢操作。因此,當調用ToList()方法時。數據庫連接必須打開。這可以通過ABP中的UnitOfWork特性標記調用者方法來實現。注意:應用服務方法默認已經是UnitOfWork,因此,即使沒有為應用服務層方法添加UnitOfWork特性,GetAll()方法也會正常工作。

這些方法也存在用于異步編程模型的asyn版本。

自定義返回值

也存在提供了IQueryable的額外方法,在調用的方法中不需要使用UnitOfWork。

T Query<T>(Func<IQueryable<TEntity>, T> queryMethod);

Query方法接受一個接收IQueryable的lambda(或方法),并返回任何對象的類型。例子如下:

var people = _personRepository.Query(q => q.Where(p => p.Name.Contains("H")).OrderBy(p => p.Name).ToList());

在該倉儲方法中,因為執行了給定的lambda(或方法),它是在數據庫連接打開的時候執行的。你可以返回實體列表,單個實體,一個投影或者執行了該查詢的其他東西。

插入

IRepository接口定義了將一個實體插入數據庫的簡單方法:

TEntity Insert(TEntity entity); Task<TEntity> InsertAsync(TEntity entity); TPrimaryKey InsertAndGetId(TEntity entity); Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity); TEntity InsertOrUpdate(TEntity entity); Task<TEntity> InsertOrUpdateAsync(TEntity entity); TPrimaryKey InsertOrUpdateAndGetId(TEntity entity); Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity);

Insert方法簡化了將一個實體插入數據庫,并將剛剛插入的實體返回。InsertAndGetId方法返回了新插入實體的Id。如果實體的Id是自動增長的并且需要最新插入實體的Id,那么該方法很有用。InsertOrUpdate方法通過檢查Id的值插入或更新給定的實體。最后,當插入或者更新之后,InsertOrUpdateAndGetId返回該實體的值。

所有的方法都存在用于異步編程模型的async版本。

更新

IRepository定義了一個方法來更新數據庫中已存在的實體。它可以獲得要更新的實體并返回相同的實體對象。

TEntity Update(TEntity entity); Task<TEntity> UpdateAsync(TEntity entity);

刪除

IRepository定義了從數據庫中刪除一個已存在的實體的方法。

void Delete(TEntity entity); Task DeleteAsync(TEntity entity); void Delete(TPrimaryKey id); Task DeleteAsync(TPrimaryKey id); void Delete(Expression<Func<TEntity, bool>> predicate); Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);

第一個方法接受一個已存在的實體,第二個方法接受一個要刪除的實體的Id。

最后一個方法接受一個刪除符合給定條件的所有實體的方法。注意,匹配給定謂詞的所有實體都會從數據庫中檢索到然后被刪除。因此,小心使用它,如果給定的條件存在太多的實體,那么可能會造成性能問題。

其他

IRepository也提供了獲得表中實體數量的方法。

int Count(); Task<int> CountAsync(); int Count(Expression<Func<TEntity, bool>> predicate); Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate); long LongCount(); Task<long> LongCountAsync(); long LongCount(Expression<Func<TEntity, bool>> predicate); Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate);

關于異步方法

ABP支持異步編程模型(APM)。因此,倉儲方法有異步版本。下面是一個使用了異步模型的應用服務方法樣例:

public class PersonAppService : AbpWpfDemoAppServiceBase, IPersonAppService {private readonly IRepository<Person> _personRepository;public PersonAppService(IRepository<Person> personRepository){_personRepository = personRepository;}public async Task<GetPeopleOutput> GetAllPeople(){var people = await _personRepository.GetAllListAsync();return new GetPeopleOutput{People = Mapper.Map<List<PersonDto>>(people)};} }

GetAllPeople方法是異步的,并使用了具有await關鍵字的GetAllListAsync方法。

也許不是所有的ORM框架都支持Async,但是EntityFramework支持。如果不支持,異步倉儲方法就會同步進行。比如,在EF中,InsertAsync和Insert是等效的,因為直到工作單元完成(Dbcontext.SaveChanges),EF才會將新的實體寫入數據庫。

倉儲實現

ABP的設計獨立于一個特定的ORM(對象/關系映射)框架或者訪問數據庫的其他技術。通過實現倉儲接口,可以使用任何框架。

ABP使用NHibernate和?EntityFramework實現了開箱即用的倉儲。關于這兩個ORM框架可以關注后面的文檔。

當使用NHibernate或EntityFramework時,如果標準方法是足夠使用的話,那么不必為實體類創建倉儲了。你可以直接注入IRepository(或IRepository)。下面是使用了一個倉儲將一個實體插入數據庫的應用服務例子:,tprimarykey>

public class PersonAppService : IPersonAppService {private readonly IRepository<Person> _personRepository;public PersonAppService(IRepository<Person> personRepository){_personRepository = personRepository;}public void CreatePerson(CreatePersonInput input){ person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };_personRepository.Insert(person);} }

PersonAppService構造注入了IRepository,并使用了Insert方法。這樣,當你需要為一個實體創建一個自定義倉儲方法時,你才應該為該實體創建一個倉儲類。

管理數據庫連接

在倉儲方法中,數據庫連接是沒有打開的或是關閉的。ABP對于數據庫連接的管理是自動處理的。

當將要進入一個倉儲方法時,數據庫連接會自動打開,并且事務自動開始。當倉儲方法結束并返回的時候,ABP會自動完成:保存所有的更改,完成事務的提交和關閉數據庫連接。如果倉儲方法拋出任何類型的異常,那么事務會自動回滾并關閉數據庫。這對于所有的實現了IRepository接口的類的公共方法都是成立的。

如果一個倉儲方法調用了其他的倉儲方法,那么它們會共享相同的連接和事務。進入倉儲的第一個方法會管理數據庫的連接。更多信息,請留意后面博客的工作單元。

一篇不錯的數據庫連接博客:細說數據庫連接

倉儲的生命周期

所有的倉儲實例都是Transient(每次使用時都會實例化)的。ABP強烈推薦使用依賴注入技術。當一個倉儲類需要注入時,依賴注入的容器會自動創建該類的新實例。

倉儲最佳實踐

  • 對于一個T類型的實體,使用IRepository倉儲接口。除非真的需要,否則不要創建自定義的倉儲。預定義的倉儲方法對于很多情況足夠用了。
  • 如果你正在創建一個自定義的倉儲(通過擴展IRepository):
    • 倉儲類應該是無狀態的。這意味著,你不應該定義倉儲級別的狀態對象,而且一個倉儲方法調用不應該影響其他的調用。
    • 自定義倉儲方法不應該包含業務邏輯或者應用邏輯,而應該只執行數據相關的或者orm特定的任務。
    • 當倉儲使用依賴注入時,給其他服務定義更少的或者不要定義依賴。


本文轉自tkbSimplest博客園博客,原文鏈接:http://www.cnblogs.com/farb/p/ABPRepository.html,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的ABP理论学习之仓储的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日日操夜夜操狠狠操 | 色爽视频 | 久久av无码精品人妻出轨 | 日本高清不卡二区 | 熟女丰满老熟女熟妇 | 欧美成人一区在线 | 殴美一级特黄aaaaaa | 麻豆网站在线看 | 九热视频在线观看 | 日韩欧美久久精品 | 人妻精品一区 | 久久综合亚洲 | 噜噜噜亚洲色成人网站 | 亚洲av无码乱码国产精品fc2 | 国产吞精囗交免费视频 | 欧美成人免费一级 | 少妇又色又爽又高潮极品 | 日韩精品免费在线视频 | 天堂va欧美va亚洲va老司机 | 午夜视频网| 久久人人爽人人爽人人片亚洲 | 刘亦菲一区二区三区免费看 | 国精品人妻无码一区二区三区喝尿 | 致单身男女免费观看完整版 | 欧美成人精品在线 | 美女视频黄a视频全免费观看 | chinesepron hd videos国产91 | 综合久久亚洲 | 波多野结衣www | 狠狠操狠狠操狠狠操 | 国产亚洲色婷婷久久 | 久久精品国产亚洲av麻豆蜜芽 | 久久久夜精品 | 最新中文字幕在线 | 欧美大尺度做爰啪啪床戏明星 | 成人午夜免费在线观看 | 精品国产91久久久久久 | 欧美日韩激情视频 | av在线最新 | 午夜在线观看视频 | 黄色三级在线观看 | 韩国三级hd两男一女 | 亚洲国产视频一区二区 | 日韩天天操| 五月婷网站 | 日b视频免费 | 成年人视频网 | 久久久久久av无码免费看大片 | 国精产品一区一区三区有限公司杨 | 粉嫩av一区二区三区天美传媒 | 色婷婷九月 | 青春草在线视频免费观看 | 少妇人妻邻居 | 泽村玲子在线 | 九热在线视频 | 天天高潮夜夜爽 | 中日韩av电影 | 三级免费黄录像 | 精品免费一区二区三区 | 久久精品tv | 亚洲综合在线视频 | 三级亚洲 | 成年人黄色大全 | 午夜寂寞视频 | 91大神精品| 日韩欧美在线中文字幕 | 成人国产 | 国产精品美女久久久久图片 | 成年人免费看的视频 | 麻豆91在线 | 亚洲色偷偷综合亚洲av伊人 | 久草新 | 污版视频在线观看 | 在线观看的毛片 | 麻豆成人精品国产免费 | 亚洲一区二区三区日韩 | 深夜的私人秘书 | 亚洲精品欧美日韩 | 亚洲影视一区二区 | 91高潮大合集爽到抽搐 | 免费在线a| 国产精品免费av一区二区三区 | 国产乱人乱偷精品视频a人人澡 | 天天干天天草天天射 | 日韩一级久久 | 在线日韩一区 | 色01看片网 | 2018天天操| 狠狠躁18三区二区一区 | 亚洲精品国产99 | 亚洲男人天堂视频 | 国产麻豆精品一区二区 | 邵氏电影《金莲外传2》免费观看 | 国产肥熟 | 日本老师巨大bbw丰满 | 久久福利在线 | 久久婷婷五月综合色国产香蕉 | 伊人二区 | 熟女少妇内射日韩亚洲 |