• 数据访问模式之Repository模式


    数据访问模式之Repository模式

     

    数据访问层无非就是对数据进行增删改查,其中增、删、改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子类都会继承增、删、改这些方法,这样我们就避免了每个实体都要重复实现这些方法。一句话概括就是:通过接口 泛型 与ORM结合 实现了数据访问层更好的复用。

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

    下面我们就用EF来实现一个简单的Repository模式 

    1、我们对实体的公共操作部分,提取为IRepository接口,比如常见的增加,删除、修改等方法。如下代码

    我们发现接口的泛型TEntity有一个约束需要继承BaseEntityBaseEntity就是把实体中公共的属性抽取出来,比如:Id(主键),CreateDate(创建时间)等。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Repository.Model;
    using System.Data.Entity;
    
    namespace Repository.Data
    {
        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);
    
        }
    }
    复制代码

    2、BaseEntity

    BaseEntity类中定义了所有参加数据操作实体的公共属性,因此我们把该类定义为抽象类,作为派生类的的基类。代码如下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.DataAnnotations;
    
    namespace Repository.Model
    {
        public abstract class BaseEntity
        {
            public BaseEntity()
            {
                Id = Guid.NewGuid();
                CreateDate = DateTime.Now;
            }
            [Key]
            public Guid Id { get; set; }
            public DateTime CreateDate { get; set; }
        }
    }
    复制代码

    3、IRepository接口定义完毕,肯定需要一个雷来实现接口中的方法,下面我们定义一个抽象类EFRepositoryBase来实现该接口方法

    我们用一个抽象类EFRepositoryBase来实现接口中的方法,这样派生的类都具有接口中定义的方法,也防止EFRepositoryBase直接被实例化,下面我们直接看代码:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Repository.Model;
    using System.Data.Entity;
    
    namespace Repository.Data
    {
        public abstract class EFRepositoryBase<TEntity> : IRepository<TEntity> where TEntity:BaseEntity
        {
            DemoDbContext Db = new DemoDbContext();
           
            #region IRepository<TEntity> 成员
    
            public DbSet<TEntity> Entities
            {
                get { return Db.Set<TEntity>(); }
            }
    
            public int Insert(TEntity entity)
            {
                Db.Set<TEntity>().Add(entity);
                return Db.SaveChanges();
            }
    
            public int Insert(IEnumerable<TEntity> entities)
            {
                throw new NotImplementedException();
            }
            public int Update(TEntity entity)
            {
                return 0;
            }
            public int Delete(object id)
            {
                throw new NotImplementedException();
            }
    
            public TEntity GetByKey(object key)
            {
                return Db.Set<TEntity>().Find(key);
    
            }
    
            #endregion
        }
    }
    复制代码

    因为我们用的EF作为数据访问,因此我们需要定义一个数据上下文,代码如下

    复制代码
     DemoDbContext()
    复制代码
    复制代码
     数据库连接字符串
    复制代码

    我们一共定义两个实体,一个是Members(学生)类和Scores(成绩)类,Members与Scores为一对多的关系。

    4、Members类和Scores类,都要继承BaseEntity基类

    复制代码
     Member
    复制代码
    复制代码
     Score
    复制代码

    基础工作都已经完成了,下面我们来看 MemberRepository.cs类和ScoreRespository.cs类。

    所有的数据操作都在EFRepositoryBase.cs中实现了,因此MemberRepository.cs和ScoreRespository.cs只需要继承EFRepositoryBase,即可实现增删改查。

    1、MemberRepository.cs

    MemberRepository为实体Member的操作类,因此EFRepositoryBase基类中的泛型被替换成实体Member,这样该类中就已经有了对Member的增删改查操作,我们也可以在MemberRepository中定义其他方法。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Repository.Model;
    
    namespace Repository.Data
    {
        public class MemberRepository : EFRepositoryBase<Member>, IRepository<Member>
        {
        }
        
    }
    复制代码

    2、ScoreRespository.cs

    ScoreRespository与MemberRepository一样,只不过是对实体Score的操作。

    3、简单测试

    复制代码
    public void test()
            {
                MemberRepository mr = new MemberRepository();
                var entity = new Member()
                {
                    UserName = "eric",
                    Age = 25,
                    Sex = ""
                };
                mr.Insert(entity);
    
                var score = new Score()
                {
                    MemberId = entity.Id,
                    Scores = 80,
                    courseId = Guid.NewGuid()
                };
                ScoreRespository sr = new ScoreRespository();
                sr.Insert(score);
            }
    复制代码

    我们发现数据操作成功。

    一般Repository都会跟Unit of Work模式联合使用,如果你有好的学习资料欢迎分享,Unit of Work模式曾看了一天也没有理解其精髓。

    每天学习一点点,每天进步一点点。

     
     
     
  • 相关阅读:
    eclipse部署web项目至本地的tomcat但在webapps中找不到
    tomcat使用jdbc连接mysql出现的错误
    MySQL-5.6.13解压版(zip版)安装配置教程
    mysql简单用法
    关于java代理(静态代理和动态代理)
    shell 基础
    一、Django入门
    java 强制类项转换
    Java多态性详解——父类引用子类对象
    Java中抽象类和接口的区别
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3267529.html
Copyright © 2020-2023  润新知