zoukankan      html  css  js  c++  java
  • 项目架构开发:数据访问层之Repository

    http://www.cnblogs.com/lanxiaoke/category/958831.html 架构设计

    接上文 项目架构开发:数据访问层之Logger

    本章我们继续IRepository开发,这个仓储与领域模式里边的仓储有区别,更像一个工具类,也就是有些园友说的“伪仓储”,

    这个仓储只实现单表的CURD与Query,都是通过主键ID或拉姆达表达式进行操作的,返回的都是单表的实体或实体集合,

    多表的在IQuery接口中再讲;虽然如此,但是如果与“活动记录”开发模式搭配的话,会非常合适,可以减少开发的时间

    及出错几率,更符合开发人员的类型调用习惯

    IRepository.cs

    复制代码
     1     public interface IRepository<T> where T : class
     2     {
     3         void Add(T entity);
     4         void AddBatch(IEnumerable<T> entitys);
     5         void Update(T entity);
     6         void Delete(T entity);
     7         void Delete(string Id);
     8         void Delete(int Id);
     9         void Delete(Guid Id);
    10         T Get(string Id);
    11         T Get(Guid Id);
    12         T Get(int Id);
    13         T Get(T entity);
    14         T Get(Expression<Func<T, bool>> func);
    15         IEnumerable<T> GetAll();
    16         IEnumerable<T> GetList(Expression<Func<T, bool>> where = null, Expression<Func<T, bool>> order = null);
    17         Tuple<int, IEnumerable<T>> GetPage(Page page, Expression<Func<T, bool>> where = null, Expression<Func<T, bool>> order = null);
    18         long Count(Expression<Func<T, bool>> where = null);
    19     }
    复制代码

    仓储的实现

    这里我们只实现dapper的适配,EF有时间再搞吧

    dapper大家应该都比较熟悉吧,不懂的朋友可以在园中搜索一下啊,很多案例

    DapperRepository.cs

    复制代码
      1 using Dapper.Contrib.Extensions;
      2 using LjrFramework.Common;
      3 using LjrFramework.Interface;
      4 using System;
      5 using System.Collections.Generic;
      6 using System.Data;
      7 using System.Linq;
      8 using System.Linq.Expressions;
      9 
     10 namespace LjrFramework.Data.Dapper
     11 {
     12     public class DapperRepository<T> : IRepository<T> where T : class
     13     {
     14         protected IDbConnection Conn { get; private set; }
     15 
     16         public DapperRepository()
     17         {
     18             Conn = DbConnectionFactory.CreateDbConnection();
     19         }
     20 
     21         public void SetDbConnection(IDbConnection conn)
     22         {
     23             Conn = conn;
     24         }
     25 
     26         public void Add(T entity)
     27         {
     28             Conn.Insert<T>(entity);
     29         }
     30 
     31         public void AddBatch(IEnumerable<T> entitys)
     32         {
     33             foreach (T entity in entitys)
     34             {
     35                 Add(entity);
     36             }
     37         }
     38 
     39         public void Update(T entity)
     40         {
     41             Conn.Update(entity);
     42         }
     43 
     44         public void Delete(T entity)
     45         {
     46             Conn.Delete(entity);
     47         }
     48 
     49         public void Delete(string Id)
     50         {
     51             var entity = Get(Id);
     52             if (entity == null) return;
     53 
     54             Delete(entity);
     55         }
     56 
     57         public void Delete(int Id)
     58         {
     59             var entity = Get(Id);
     60             if (entity == null) return;
     61 
     62             Delete(entity);
     63         }
     64         public void Delete(Guid Id)
     65         {
     66             var entity = Get(Id);
     67             if (entity == null) return;
     68 
     69             Delete(entity);
     70         }
     71 
     72         public T Get(T entity)
     73         {
     74             return Conn.Get<T>(entity);
     75         }
     76 
     77         public T Get(Guid Id)
     78         {
     79             return Conn.Get<T>(Id);
     80         }
     81 
     82         public T Get(string Id)
     83         {
     84             return Conn.Get<T>(Id);
     85         }
     86 
     87         public T Get(int Id)
     88         {
     89             return Conn.Get<T>(Id);
     90         }
     91 
     92         public T Get(Expression<Func<T, bool>> func)
     93         {
     94             var linqToWhere = new LinqToWhere<T>();
     95             linqToWhere.Parse(func);
     96             
     97             return Conn.GetByFunc<T>(linqToWhere.Where, linqToWhere.KeyValuePairs);
     98         }
     99 
    100         public IEnumerable<T> GetAll()
    101         {
    102             return Conn.GetAll<T>();
    103         }
    104 
    105         public IEnumerable<T> GetList(Expression<Func<T, bool>> where = null, Expression<Func<T, bool>> order = null)
    106         {
    107             where = where.And(order);
    108 
    109             var linqToWhere = new LinqToWhere<T>();
    110             linqToWhere.Parse(where);
    111 
    112             return Conn.GetListByFunc<T>(linqToWhere.Where, linqToWhere.KeyValuePairs);
    113         }
    114 
    115         public Tuple<int, IEnumerable<T>> GetPage(Page page, Expression<Func<T, bool>> where = null, Expression<Func<T, bool>> order = null)
    116         {
    117             where = where.And(order);
    118 
    119             var linqToWhere = new LinqToWhere<T>();
    120             linqToWhere.Parse(where);
    121 
    122             var multi = Conn.GetPage<T>(page.PageIndex, page.PageSize, linqToWhere.Order, linqToWhere.Where, linqToWhere.KeyValuePairs);
    123             var count = multi.Read<int>().Single();
    124             var results = multi.Read<T>();
    125 
    126             return new Tuple<int, IEnumerable<T>>(count, results);
    127         }
    128 
    129         public long Count(Expression<Func<T, bool>> where = null)
    130         {
    131             var linqToWhere = new LinqToWhere<T>();
    132             linqToWhere.Parse(where);
    133 
    134             return Conn.Count<T>(linqToWhere.Where, linqToWhere.KeyValuePairs);
    135         }
    136     }
    137 }
    复制代码

    注意标红的那行,Conn的所有方法都是在命名空间(Dapper.Contrib.Extensions)下的扩展方法

    我们看看其中的Insert实现方式,为什么直接传递T就可以,而不用写sql语句

    可以看到,dapper后台是遍历实体的属性,最后也是拼凑成符合格式的sql语句;

    这一点也可以自己扩展,有很大的便利性,所以他写在Extensions中

    DbConnectionFactory.cs 也很简单,是dapper支持多数据库的工厂类

    复制代码
     1 public class DbConnectionFactory
     2     {
     3         private static readonly string connectionString;
     4         private static readonly string databaseType;
     5 
     6         static DbConnectionFactory()
     7         {
     8             var collection = ConfigurationManager.ConnectionStrings["connectionString"];
     9             connectionString = collection.ConnectionString;
    10             databaseType = collection.ProviderName.ToLower();
    11         }
    12 
    13         public static IDbConnection CreateDbConnection()
    14         {
    15             IDbConnection connection = null;
    16             switch (databaseType)
    17             {
    18                 case "system.data.sqlclient":
    19                     connection = new System.Data.SqlClient.SqlConnection(connectionString);
    20                     break;
    21                 case "mysql":
    22                     //connection = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
    23                     break;
    24                 case "oracle":
    25                     //connection = new Oracle.DataAccess.Client.OracleConnection(connectionString);
    26                     //connection = new System.Data.OracleClient.OracleConnection(connectionString);
    27                     break;
    28                 case "db2":
    29                     connection = new System.Data.OleDb.OleDbConnection(connectionString);
    30                     break;
    31                 default:
    32                     connection = new System.Data.SqlClient.SqlConnection(connectionString);
    33                     break;
    34             }
    35             return connection;
    36         }
    37     }
    复制代码

    自此,dapper适配的仓储就完成了

    我们在测试项目中看看效果,这里我们不在继续在基础设施里添加仓储了,用另一种方式:IOC

    项目引用Autofac,用依赖出入来初始化IRepository<T>接口

    测试仓储功能

    复制代码
     1 [TestClass]
     2     public class DapperRepositoryTest
     3     {
     4         private IRepository<LoginUser> repository;
     5 
     6         public DapperRepositoryTest()
     7         {
     8             var builder = new ContainerBuilder();
     9             builder.RegisterType<DapperRepository<LoginUser>>().As<IRepository<LoginUser>>();
    10 
    11             var container = builder.Build();
    12             repository = container.Resolve<IRepository<LoginUser>>();
    13         }
    14 
    15         [TestMethod]
    16         public void Add()
    17         {
    18             var loginUser = new LoginUser()
    19             {
    20                 Id = Guid.NewGuid(),
    21                 LoginName = "lanxiaoke-" + Guid.NewGuid().ToString(),
    22                 Password = "mima1987",
    23                 IsEnabled = 1,
    24                 CreateTime = DateTime.Now
    25             };
    26 
    27             repository.Add(loginUser);
    28 
    29             long count = repository.Count(t => t.LoginName == loginUser.LoginName);
    30 
    31             Assert.AreEqual(true, count == 1);
    32         }
    33 
    34         [TestMethod]
    35         public void Get()
    36         {
    37             var loginUser = new LoginUser()
    38             {
    39                 Id = Guid.NewGuid(),
    40                 LoginName = "lanxiaoke-" + Guid.NewGuid().ToString(),
    41                 Password = "mima1987",
    42                 IsEnabled = 1,
    43                 CreateTime = DateTime.Now
    44             };
    45             repository.Add(loginUser);
    46 
    47             var tmp = repository.Get(loginUser.Id);
    48             Assert.AreEqual(loginUser.Id, tmp.Id);
    49 
    50             var tmp2 = repository.Get(w => w.Id == loginUser.Id && w.IsEnabled == loginUser.IsEnabled);
    51             Assert.AreEqual(loginUser.Id, tmp2.Id);
    52         }
    53         ...//限于篇幅,只写这么多了,大部分代码都差不多
    54     }
    复制代码

    注意这句:container.Resolve<IRepository<LoginUser>>(); 这句就是实现初始化IRepository<T>接口;

    如何初始化呢?看上一句:builder.RegisterType<DapperRepository<LoginUser>>().As<IRepository<LoginUser>>(); 直接注册DapperRepository就可以了

    其实这里也可以用配置的方式初始化IRepository<T>,这样就可以避免DapperRepository<T>与业务层耦合了

    测试项目,我们就暂且这么写吧。

    我们来看看效果

    下边都是这次测试生成的数据

    自此 IRepository 就开发完成了

    项目架构开发系列

     
    分类: 架构设计
  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/webenh/p/9178733.html
Copyright © 2011-2022 走看看