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

  • 相关阅读:
    (转)AS3中实现卡马克卷轴算法
    (转)flash位图缓存cacheAsBitmap
    (转)addFrameScript函数的纠结
    (转)flash安全策略文件
    (转)脏矩形技术学习
    (转)stopImmediatePropagation 和stopPropagation的区别
    (转)flash对象池技术
    揭开嵌入式C面试题背后的玄机
    一次遍历找链表倒数第n个节点
    N!的尾部连续0的个数
  • 原文地址:https://www.cnblogs.com/aehyok/p/3391675.html
Copyright © 2020-2023  润新知