Entity Framework Repository模式

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.簡單調用

 

能夠看到就這樣便可進行調用處理。

總結

 

 簡單的項目分層,這裏只是簡單的處理分層,並無真正意義上的。僅供參考。

簡單測試項目下載連接地址

Entity Framework 5.0基礎系列目錄

相關文章
相關標籤/搜索