zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    MySQL补充
    不同操作系统下虚拟环境的搭建
    Python导学基础(二)变量与基础数据类型
    Python导学基础(一)介绍
    KM 算法
    题解-CF1065E Side Transmutations
    题解-CF1140E Palindrome-less Arrays
    题解-CF677D Vanya and Treasure
    splay文艺平衡树
    splay区间操作(bzoj1500)
  • 原文地址:https://www.cnblogs.com/kellynic/p/10406319.html
Copyright © 2011-2022 走看看