Repository模式以前html
若是咱們用最原始的EF進行設計對每一個實體類的「C(增長)、R(讀取)、U(修改)、D(刪除)」這四個操做。數據庫
第一個:先來看看查詢,對於實體類簡單的查詢操做,每次都是這樣的過程會在代碼中擁有大量的重複 極爲相似的代碼段。設計模式
using (var db = new EFContext("EFContext")) { var persons = db.Persons.Where(t => t.PersonName == "aehyok").OrderByDescending(t => t.PersonId).ToList(); foreach (var p in persons) { Console.WriteLine("The PersonName is {0} and Age {1}", p.PersonName, p.Age); } } Console.ReadLine();
第二個:對於實體類的添加操做。架構
using (var db = new EFContext()) { var stephen = new Person { PersonName="aehyok0001", Age=25, Address="深圳南山", Email="aehyok@163.com" }; db.Persons.Add(stephen); db.Persons.Attach(stephen); db.Entry(stephen).State = EntityState.Unchanged; ////同上面db.Persons.Attach(stephen);做用是同樣的 var jeffrey = new Person { PersonName = "aehyok0002", Age = 25, Address = "深圳寶安", Email = "Leo@163.com" }; db.Entry(jeffrey).State = EntityState.Added; db.SaveChanges(); }
第三個:同理,刪除操做以下。ide
using (var db = new EFContext()) { var person = db.Persons.Where(m => m.PersonId == 4).FirstOrDefault(); db.Persons.Remove(person); db.SaveChanges(); }
第四個:同理,修改操做以下。測試
using (var db = new EFContext()) { var person = db.Persons.Where(m => m.PersonId == 4).FirstOrDefault(); db.Persons.Remove(person); db.SaveChanges(); }
以上基於一個實體類簡單的CURD操做,固然對於查詢變幻無窮。在數據訪問層,咱們能夠專門的爲每一個類進行封裝業務處理類,可是其中類與類之間相同或相似的代碼段太多,對於編碼人員來講,更是浪費時間,一樣的代碼,要在項目的不一樣使用地方,進行屢次的複製修改幾個代碼字段便可使用,那麼咱們爲何不進行簡單的封裝處理,來讓這一過程變得更加簡單,且使咱們的代碼變得更爲優雅,讓開發人員的維護操做更爲簡單,也更易於擴展。基於以上考慮引出了咱們的Repository設計模式。ui
Repository設計模式編碼
在《企業架構模式》中,譯者將Repository翻譯爲資源庫。給出以下說明:經過用來訪問領域對象的一個相似集合的接口,在領域與數據映射層之間進行協調。spa
那麼基於Rspository模式,數據訪問層無非就是對數據進行增刪改查,其中增、刪、改等咱們能夠抽象出來寫一個公共的接口或抽象類來定義這些方法,並採用一個基類實現這些方法,這樣該基類派生的子類都會繼承增、刪、改這些方法,這樣咱們就避免了每一個實體都要重複實現這些方法。一句話歸納就是:經過接口 泛型 與ORM結合 實現了數據訪問層更好的複用。翻譯
Repository代碼實現
1.EF實例數據操做上下文對象
主要進行初始化數據庫,並進行設置自動更新數據庫
public class EFContext:DbContext { public EFContext() : base("default") { Database.SetInitializer<EFContext>(new MigrateDatabaseToLatestVersion<EFContext,EFDbMigrationsConfiguration>()); } public DbSet<Member> Members { get; set; } public DbSet<Score> Scores { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); modelBuilder.Entity<Member>().HasMany(b => b.Scores); } } internal sealed class EFDbMigrationsConfiguration : DbMigrationsConfiguration<EFContext> { public EFDbMigrationsConfiguration() { AutomaticMigrationsEnabled = true;//任何Model Class的修改將會自動直接更新DB AutomaticMigrationDataLossAllowed = true; //可接受自動遷移期間的數據丟失的值 } }
2.BaseEntity類
BaseEntity類中定義了全部參加數據操做實體的公共屬性,所以咱們把該類定義爲抽象類,做爲派生類的的基類。
public abstract class BaseEntity { [Key] public Guid Id { get; set; } public DateTime CreateDate { get; set; } public BaseEntity() { Id = Guid.NewGuid(); CreateDate = DateTime.Now; } }
3.Repository模式中最底層的接口實現IRepository
咱們對實體的公共操做部分,提取爲IRepository接口,好比常見的增長,刪除、修改等方法。
public interface IRepository<TEntity> where TEntity:BaseEntity { DbSet<TEntity> Entities { get; } //增長單個實體 int Insert(TEntity entity); //增長多個實體 int Insert(IEnumerable<TEntity> entities); //更新實體 int Update(TEntity entity); //刪除 int Delete(object id); //根據逐漸獲取實體 TEntity GetByKey(object key); }
其中的接口方法的定義,也會根據具體項目中業務,來進行定義適應自身的方法。具備必定的靈活性
咱們發現接口的泛型TEntity有一個約束須要繼承BaseEntity,BaseEntity就是把實體中公共的屬性抽取出來,好比:Id(主鍵),CreateDate(建立時間)等。
4.Repository模式中基於接口的抽象類EFRepositoryBase
咱們用一個抽象類EFRepositoryBase來實現接口中的方法,這樣派生的類都具備接口中定義的方法,也防止EFRepositoryBase直接被實例化。
public abstract class EFRepositoryBase<TEntity>:IRepository<TEntity> where TEntity:BaseEntity { EFContext EF = new EFContext(); public DbSet<TEntity> Entities { get { return EF.Set<TEntity>(); } } public int Insert(TEntity entity) { Entities.Add(entity); return EF.SaveChanges(); } public int Insert(IEnumerable<TEntity> entities) { Entities.AddRange(entities); return EF.SaveChanges(); } public int Update(TEntity entity) { EF.Entry(entity).State = EntityState.Modified; return EF.SaveChanges(); } public int Delete(object id) { ///刪除操做實現 return 0; } public TEntity GetByKey(object key) { return Entities.Find(key); } }
5.簡單調用
能夠看到就這樣便可進行調用處理。
總結
簡單的項目分層,這裏只是簡單的處理分層,並無真正意義上的。僅供參考。
簡單測試項目下載連接地址