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层混合起来,需要多个项目配合结构清晰的进行分层工作,本文根据个人实践经验总结将各个项目进 ...
随机推荐
- Python Django开发中XSS内容过滤问题的解决
from:http://stackoverflow.com/questions/699468/python-html-sanitizer-scrubber-filter 通过下面这个代码就可以把内容过 ...
- WebRTC技术调研
相关网址: 协议:https://www.w3.org/TR/webrtc/ https://apprtc.webrtc.org/ https://apprtc.appspot.com/ https: ...
- Django push: Using Server-Sent Events and WebSocket with Django
http://curella.org/blog/2012/jul/17/django-push-using-server-sent-events-and-websocket/ The goal of ...
- 开始记录学习java的笔记
今天开始记录学习java的笔记,加油
- php中获取用户登陆的IP地址以及常规处理
本文为原创,转载请注明! 在我们开发多站点业务网站中,经常需要获取客户端的ip地址来给用户推荐其所在地址的信息的业务,用php获取客户端的ip地址,我们一般用到的PHP内置方法是$_SERVER[' ...
- DataTime显示格式【转】
随心所欲的DateTime显示格式 任何项目,难免会碰到DateTime的显示问题,.net框架虽提供丰富多样的显示方法,但我很少使用,因老忘记细节,每次都要纠结到底月份在前还是年份在前:日期分隔符到 ...
- Android 开发TCP协议时,报错NetworkOnMainThreadException
设想是通过Android应用连接PC的TCP服务器,通过点击按钮连接服务器, 最终在点击按钮后报错:networkonmainthreadexception 解决办法: 在MainActivity文件 ...
- 网络-udp
1. 网络:把双方或者多方的设备(电脑,智能手机,ipad等)连接起来的一个工具 1.1 学习网络的目的: 通过网络把数据从一方传递到另外一方,完成数据的共享 2. ip地址 2.1: ...
- vsts + XX云服务器构建netcore+docker持续集成交付部署
持续集成交付部署是什么意思,它给我们带来什么好处? 先贴一张图 持续集成(Continuous Integration) 持续集成强调开发人员提交了新代码之后,立刻进行构建.(单元)测试(这个要看情况 ...
- Python 3.6 中文手册——前言
1. 前言 如果你在电脑上做了很多工作,最终你会发现有一些任务你想要自动化.例如,你可能希望对大量的文本文件执行搜索和替换,或者以复杂的方式重命名并排列一堆照片文件.也许你想写一个小的自定义数据库,或 ...