前言

好多年前,DAL 作为数据库访问层,其实是非常流行的命名方式。

不知道从什么时候开始,仓储层成了新的时尚名词。目前了解到,许多人只要在项目中看见 DAL 就会觉得很 low,但是比较可笑的一点是,多数的仓储层与 DAL 实质在做同样的事情。

本文正要介绍这种比较 low 的方式,来现实通用的仓储层。

参考规范

与其他规范标准一样,仓储层也有相应的规范定义。FreeSql.Repository 参考 abp vnext 代码,定义和实现基础的仓储层(CURD),应该算比较通用的方法吧。

IBasicRepository.cs 增删改接口

using System.Threading.Tasks;

namespace FreeSql {
public interface IBasicRepository<TEntity> : IReadOnlyRepository<TEntity>
where TEntity : class {
TEntity Insert(TEntity entity);
Task<TEntity> InsertAsync(TEntity entity); void Update(TEntity entity);
Task UpdateAsync(TEntity entity);
IUpdate<TEntity> UpdateDiy { get; } void Delete(TEntity entity);
Task DeleteAsync(TEntity entity);
} public interface IBasicRepository<TEntity, TKey> : IBasicRepository<TEntity>, IReadOnlyRepository<TEntity, TKey>
where TEntity : class {
void Delete(TKey id);
Task DeleteAsync(TKey id);
}
}

IReadOnlyRepository.cs 查询接口

using System.Threading.Tasks;

namespace FreeSql {
public interface IReadOnlyRepository<TEntity> : IRepository
where TEntity : class {
ISelect<TEntity> Select { get; }
} public interface IReadOnlyRepository<TEntity, TKey> : IReadOnlyRepository<TEntity>
where TEntity : class {
TEntity Get(TKey id);
Task<TEntity> GetAsync(TKey id); TEntity Find(TKey id);
Task<TEntity> FindAsync(TKey id);
}
}

IRepository.cs 仓储接口

using System;
using System.Linq.Expressions;
using System.Threading.Tasks; namespace FreeSql { public interface IRepository {
//预留
} public interface IRepository<TEntity> : IReadOnlyRepository<TEntity>, IBasicRepository<TEntity>
where TEntity : class {
void Delete(Expression<Func<TEntity, bool>> predicate);
Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);
} public interface IRepository<TEntity, TKey> : IRepository<TEntity>, IReadOnlyRepository<TEntity, TKey>, IBasicRepository<TEntity, TKey>
where TEntity : class {
}
}

现实 BaseRepository.cs 通用的仓储基类

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks; namespace FreeSql {
public abstract class BaseRepository<TEntity> : IRepository<TEntity>
where TEntity : class {
protected IFreeSql _fsql;
public BaseRepository(IFreeSql fsql) : base() {
_fsql = fsql;
if (_fsql == null) throw new NullReferenceException("fsql 参数不可为空");
} public ISelect<TEntity> Select => _fsql.Select<TEntity>();
public IUpdate<TEntity> UpdateDiy => _fsql.Update<TEntity>(); public void Delete(Expression<Func<TEntity, bool>> predicate) => _fsql.Delete<TEntity>().Where(predicate).ExecuteAffrows();
public void Delete(TEntity entity) => _fsql.Delete<TEntity>(entity).ExecuteAffrows();
public Task DeleteAsync(Expression<Func<TEntity, bool>> predicate) => _fsql.Delete<TEntity>().Where(predicate).ExecuteAffrowsAsync();
public Task DeleteAsync(TEntity entity) => _fsql.Delete<TEntity>(entity).ExecuteAffrowsAsync(); public TEntity Insert(TEntity entity) => _fsql.Insert<TEntity>().AppendData(entity).ExecuteInserted().FirstOrDefault();
async public Task<TEntity> InsertAsync(TEntity entity) => (await _fsql.Insert<TEntity>().AppendData(entity).ExecuteInsertedAsync()).FirstOrDefault(); public void Update(TEntity entity) => _fsql.Update<TEntity>().SetSource(entity).ExecuteAffrows();
public Task UpdateAsync(TEntity entity) => _fsql.Update<TEntity>().SetSource(entity).ExecuteAffrowsAsync();
} public abstract class BaseRepository<TEntity, TKey> : BaseRepository<TEntity>, IRepository<TEntity, TKey>
where TEntity : class {
public BaseRepository(IFreeSql fsql) : base(fsql) {
} public void Delete(TKey id) => _fsql.Delete<TEntity>(id).ExecuteAffrows();
public Task DeleteAsync(TKey id) => _fsql.Delete<TEntity>(id).ExecuteAffrowsAsync(); public TEntity Find(TKey id) => _fsql.Select<TEntity>(id).ToOne();
public Task<TEntity> FindAsync(TKey id) => _fsql.Select<TEntity>(id).ToOneAsync(); public TEntity Get(TKey id) => Find(id);
public Task<TEntity> GetAsync(TKey id) => FindAsync(id);
}
}

如何使用?

1、安装

dotnet add package FreeSql.Repository

2、声明 FreeSql,为单例

var fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
.UseLogger(loggerFactory.CreateLogger<IFreeSql>())
.UseAutoSyncStructure(true) //自动迁移实体的结构到数据库
.Build();

ps: FreeSql 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite。

3、创建实体

public class Song {
[Column(IsIdentity = true)]
public int Id { get; set; }
public string Title { get; set; }
}

4、创建仓储层

public class SongRepository : BaseRepository<Song, int> {
public SongRepository(IFreeSql fsql) : base(fsql) {
}
}

解释:<Song, int> 泛值第一个参数Song是实体类型,第二个参数int为主键类型

至此,通过继承 BaseRepository 非常方便的实现了仓储层 SongRepository,他包含比较标准的 CURD 现实。

参考资料:https://github.com/2881099/FreeSql/wiki/Repository

结束语

FreeSql.Repository 的版本号目前与 FreeSql 同步更新,查看更新说明

FreeSql 特性

  • CodeFirst 迁移。
  • DbFirst 从数据库导入实体类,支持三种模板生成器。
  • 采用 ExpressionTree 高性能读取数据。
  • 类型映射深入支持,比如pgsql的数组类型,匠心制作。
  • 支持丰富的表达式函数。
  • 支持导航属性查询,和延时加载。
  • 支持同步/异步数据库操作方法,丰富多彩的链式查询方法。
  • 支持事务。
  • 支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite。

Github:https://github.com/2881099/FreeSql

FreeSql.Repository 通用仓储层功能的更多相关文章

  1. FreeSql.Repository (一)什么是仓储

    欢迎来到<FreeSql.Repository 仓储模式>系列文档,完整文档请前往 wiki 中心:https://github.com/dotnetcore/FreeSql/wiki F ...

  2. .NET ORM 仓储层必备的功能介绍之 FreeSql Repository 实现篇

    写在开头 2018年11月的某一天,头脑发热开启了 FreeSql 开源项目之旅,时间一晃已经四年多,当初从舒服区走向一个巨大的坑,回头一看后背一凉.四年时间从无到有,经历了数不清的日夜奋战(有人问我 ...

  3. 用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类

    前言 年底工作比较忙,年度总结还没写,项目要上线,回老家过年各种准备.尤其是给长辈给侄子侄女准备礼物头都大了. 原来想年前先出一版能用的,我看有点悬了,尽量先把大体功能弄出来,扔掉一些,保证能考试,然 ...

  4. (译文)MVC通用仓储类

    Generic Repository Pattern MVC Generic Repository Pattern MVC 原文链接:http://www.codeproject.com/Articl ...

  5. .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用

    书接上文,继续搭建我们基于.netCore 的开发框架.首先是我们的项目分层结构. 这个分层结构,是参考张老师的分层结构,但是实际项目中,我没有去实现仓储模型.因为我使用的是EFCore ,最近也一直 ...

  6. MVC通用仓储类

    原文链接:http://www.codeproject.com/Articles/1095323/Generic-Repository-Pattern-MVC 良好的架构师任何项目的核心,开发人员一直 ...

  7. OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现

    最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明.既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS.Core)中我对仓储 ...

  8. EF通用数据层封装类(支持读写分离,一主多从)

    浅谈orm 记得四年前在学校第一次接触到 Ling to Sql,那时候瞬间发现不用手写sql语句是多么的方便,后面慢慢的接触了许多orm框架,像 EF,Dapper,Hibernate,Servic ...

  9. EFCore+Mysql仓储层建设(分页、多字段排序、部分字段更新)

    前沿 园子里已有挺多博文介绍了EFCore+Mysql/MSSql如何进行使用,但实际开发不会把EF层放在Web层混合起来,需要多个项目配合结构清晰的进行分层工作,本文根据个人实践经验总结将各个项目进 ...

随机推荐

  1. H5之postMessage 。实现跨域

    对于跨域我们有很多的解决方案,今天我来分享一下postMessage的那点事,postMessage是html5新增的一个解决跨域的一个方法,不过很可惜万恶的ie6,7不支持 postMessage( ...

  2. Android的颜色值转换

    Android的颜色int值比较变态,是个负值,用计算机术语讲叫补码,手工转换比较麻烦,首先看看文档 https://developer.android.com/reference/android/g ...

  3. mysql Access denied for user \'root\'@\'localhost\'” 本人解决方案:

    直接上图   昨天还是好的今天就不行了,密码是没错的,就是本地的连接不上,Linux上的mysql可以连, 网上找各种解决方案,什么权限,什么加一句话,还有这个 如果连这个都进不去那就直接重装吧,其实 ...

  4. 深入理解SpringBoot之自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提.其实它并不那么神秘,我在这之前已经写过最基本的实现了,大家可以参考这篇文章.这次主要的议题是,来看看它是怎么样实现的,我们透过源代码 ...

  5. Python + Appium 环境搭建

    ---恢复内容开始--- Appium自动化公司内部测试培训1-环境搭建 课程目的 一.Python + Appium 环境搭建 课程内容 1    安装前准备工作 搭建环境所需要的安装文件已经下载好 ...

  6. python 闯关之路三(面向对象与网络编程)

    1,简述socket 通信原理 如上图,socket通信建立在应用层与TCP/IP协议组通信(运输层)的中间软件抽象层,它是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/ ...

  7. 如何高效的编写与同步博客 (.NET Core 小工具实现)

    一.前言 写博客,可以带给我们很多好处,比如可以让我们结识更多志同道合的人:在写博客过程中去查技术资料或者实践可以让我们对知识的掌握和理解更加深刻:通过博客分享能帮助他人收获分享的快乐等等.写博客真的 ...

  8. Spring Aop技术原理分析

    本篇文章从Aop xml元素的解析开始,分析了Aop在Spring中所使用到的技术.包括Aop各元素在容器中的表示方式.Aop自动代理的技术.代理对象的生成及Aop拦截链的调用等等.将这些技术串联起来 ...

  9. jQuery 素材 缩略图轮播集合

    http://www.17sucai.com/pins/demo-show?id=27124 http://www.17sucai.com/pins/demo-show?id=4712  楼盘详情缩略 ...

  10. C/C++中结构体struct 的使用

    结构(struct)      结构是由基本数据类型构成的.并用一个标识符来命名的各种变量的组合.  结构中可以使用不同的数据类型.      1. 结构说明和结构变量定义      在Turbo C ...