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基础系列目录

相关文章
相关标签/搜索