zoukankan      html  css  js  c++  java
  • Entity Framework Repository模式

    Repository模式之前

    如果我们用最原始的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();
                }

    第三个:同理,删除操作如下。

                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设计模式。

    Repository设计模式

     在《企业架构模式》中,译者将Repository翻译为资源库。给出如下说明:通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。

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

  • 相关阅读:
    numpy 基础 —— np.linalg
    图像旋转后显示不完全
    opencv ---getRotationMatrix2D函数
    PS1--cannot be loaded because the execution of scripts is disabled on this system
    打开jnlp Faild to validate certificate, the application will not be executed.
    BATCH(BAT批处理命令语法)
    oracle vm virtualbox 如何让虚拟机可以上网
    merge 实现
    Windows batch,echo到文件不成功,只打印出ECHO is on.
    python2.7.6 , setuptools pip install, 报错:UnicodeDecodeError:'ascii' codec can't decode byte
  • 原文地址:https://www.cnblogs.com/aehyok/p/3391675.html
Copyright © 2011-2022 走看看