FreeSql.Repository 通用仓储层功能

1|0前言

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

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

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

2|0参考规范

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

2|1IBasicRepository.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); } }

2|2IReadOnlyRepository.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); } }

2|3IRepository.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 { } }

3|0现实 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); } }

4|0如何使用?

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

5|0结束语

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

FreeSql 特性

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

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


__EOF__

本文作者FreeSql & CSRedis
本文链接https://www.cnblogs.com/kellynic/p/10406319.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   nicye  阅读(4669)  评论(6编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示