FreeSql.Repository 通用仓储层功能
前言
好多年前,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 通用仓储层功能的更多相关文章
- FreeSql.Repository (一)什么是仓储
欢迎来到<FreeSql.Repository 仓储模式>系列文档,完整文档请前往 wiki 中心:https://github.com/dotnetcore/FreeSql/wiki F ...
- .NET ORM 仓储层必备的功能介绍之 FreeSql Repository 实现篇
写在开头 2018年11月的某一天,头脑发热开启了 FreeSql 开源项目之旅,时间一晃已经四年多,当初从舒服区走向一个巨大的坑,回头一看后背一凉.四年时间从无到有,经历了数不清的日夜奋战(有人问我 ...
- 用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类
前言 年底工作比较忙,年度总结还没写,项目要上线,回老家过年各种准备.尤其是给长辈给侄子侄女准备礼物头都大了. 原来想年前先出一版能用的,我看有点悬了,尽量先把大体功能弄出来,扔掉一些,保证能考试,然 ...
- (译文)MVC通用仓储类
Generic Repository Pattern MVC Generic Repository Pattern MVC 原文链接:http://www.codeproject.com/Articl ...
- .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用
书接上文,继续搭建我们基于.netCore 的开发框架.首先是我们的项目分层结构. 这个分层结构,是参考张老师的分层结构,但是实际项目中,我没有去实现仓储模型.因为我使用的是EFCore ,最近也一直 ...
- MVC通用仓储类
原文链接:http://www.codeproject.com/Articles/1095323/Generic-Repository-Pattern-MVC 良好的架构师任何项目的核心,开发人员一直 ...
- OSS.Core基于Dapper封装(表达式解析+Emit)仓储层的构思及实现
最近趁着不忙,在构思一个搭建一个开源的完整项目,至于原因以及整个项目框架后边文章我再说明.既然要起一个完整的项目,那么数据仓储访问就必不可少,这篇文章我主要介绍这个新项目(OSS.Core)中我对仓储 ...
- EF通用数据层封装类(支持读写分离,一主多从)
浅谈orm 记得四年前在学校第一次接触到 Ling to Sql,那时候瞬间发现不用手写sql语句是多么的方便,后面慢慢的接触了许多orm框架,像 EF,Dapper,Hibernate,Servic ...
- EFCore+Mysql仓储层建设(分页、多字段排序、部分字段更新)
前沿 园子里已有挺多博文介绍了EFCore+Mysql/MSSql如何进行使用,但实际开发不会把EF层放在Web层混合起来,需要多个项目配合结构清晰的进行分层工作,本文根据个人实践经验总结将各个项目进 ...
随机推荐
- Fiddler - 工具配置及在ios抓取不了https的解决方法
一.首先,官网下载最新版fiddler工具: https://www.telerik.com/fiddler 二.打开fiddler,点击Tools - Options 我电脑上的各项配置如下图(也可 ...
- Kapacitor之TICK脚本,监控输出
好久没更新博客园了,说来也惭愧,之前说好每隔几天更新一个的,虽然没什么人看,但是作为一个记录,回顾也是能有新的认识,这篇博客是讲的目前我在工作中使用的一个结束点,这个技术点目前网上资料少之甚少,也是希 ...
- Scala编程入门---函数式编程之集合操作
集合的函数式编程: 实战常用: //map案例实战:为List中的每个元素都添加一个前缀. List("leo","Jen","peter" ...
- Scala编程入门---Map与Tuple
创建Map //创建一个不可变的Map val ages = Map("Leo" -> 30,"Jen" ->25,"Jack" ...
- 物流的纯css实现方法
首先我们来看看UI给出的设计图. 为什么到达是最前面,为什么物流顺序是倒叙的,这是什么用户习惯,这是我拿到设计稿的问题,但是这里不谈设计,因为审美这个东西无法评估.那么这里我就做一个顺序的来对比一下吧 ...
- lintcode 在O(1)时间复杂度删除链表节点
题目要求 给定一个单链表中的一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点. 样例 Linked list is 1->2->3->4, and giv ...
- 使用WSL连接Docker for Windows
在Windows下安装Docker for Windows Cotana搜索功能,打开Windows的Hype-v功能(注:会影响Virtualbox和Vmware的使用)并重启电脑. 从Docker ...
- 让程序跳转到绝对地址0x100000去执行
网上比较火的一个题,让程序跳转到绝对地址去执行 :可以的实现方式为: ( (void(*)())0x4110e6)(); (*(void(*)())0x4110e6)(); (*((void(*)() ...
- FastDFS单机版安装
FastDFS 分布式文件系统 1 目标 了解项目中使用FastDFS的原因和意义. 掌握FastDFS的架构组成部分,能说出tracker和storage的作用. 了解FastDFS+nginx上传 ...
- 基于.net的爬虫应用-DotnetSpider
最近应朋友的邀请,帮忙做了个简单的爬虫程序,要求不高,主要是方便对不同网站的爬取进行扩展,获取到想要的数据信息即可.当然,基于数据的后期分析功能是后话,以后的随笔我会逐步的介绍. 开源的爬虫框架比较多 ...