前言
好多年前,DAL 作为数据库访问层,其实是非常流行的命名方式。
不知道从什么时候开始,仓储层成了新的时尚名词。目前了解到,许多人只要在项目中看见 DAL 就会觉得很 low,但是比较可笑的一点是,多数的仓储层与 DAL 实质在做同样的事情。
本文正要介绍这种比较 low 的方式,来现实通用的仓储层。
参考规范
与其他规范标准一样,仓储层也有相应的规范定义。FreeSql.Repository 参考 abp vnext 代码,定义和实现基础的仓储层(CURD),应该算比较通用的方法吧。
IBasicRepository.cs 增删改接口
using System.Threading.Tasks;
namespace FreeSql {
public interface IBasicRepository : IReadOnlyRepository
where TEntity : class {
TEntity Insert(TEntity entity);
Task InsertAsync(TEntity entity);
void Update(TEntity entity);
Task UpdateAsync(TEntity entity);
IUpdate UpdateDiy { get; }
void Delete(TEntity entity);
Task DeleteAsync(TEntity entity);
}
public interface IBasicRepository : IBasicRepository, IReadOnlyRepository
where TEntity : class {
void Delete(TKey id);
Task DeleteAsync(TKey id);
}
}
IReadOnlyRepository.cs 查询接口
using System.Threading.Tasks;
namespace FreeSql {
public interface IReadOnlyRepository : IRepository
where TEntity : class {
ISelect Select { get; }
}
public interface IReadOnlyRepository : IReadOnlyRepository
where TEntity : class {
TEntity Get(TKey id);
Task GetAsync(TKey id);
TEntity Find(TKey id);
Task FindAsync(TKey id);
}
}
IRepository.cs 仓储接口
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace FreeSql {
public interface IRepository {
//预留
}
public interface IRepository : IReadOnlyRepository, IBasicRepository
where TEntity : class {
void Delete(Expression> predicate);
Task DeleteAsync(Expression> predicate);
}
public interface IRepository : IRepository, IReadOnlyRepository, IBasicRepository
where TEntity : class {
}
}
现实 BaseRepository.cs 通用的仓储基类
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace FreeSql {
public abstract class BaseRepository : IRepository
where TEntity : class {
protected IFreeSql _fsql;
public BaseRepository(IFreeSql fsql) : base() {
_fsql = fsql;
if (_fsql == null) throw new NullReferenceException("fsql 参数不可为空");
}
public ISelect Select => _fsql.Select();
public IUpdate UpdateDiy => _fsql.Update();
public void Delete(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrows();
public void Delete(TEntity entity) => _fsql.Delete(entity).ExecuteAffrows();
public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrowsAsync();
public Task DeleteAsync(TEntity entity) => _fsql.Delete(entity).ExecuteAffrowsAsync();
public TEntity Insert(TEntity entity) => _fsql.Insert().AppendData(entity).ExecuteInserted().FirstOrDefault();
async public Task InsertAsync(TEntity entity) => (await _fsql.Insert().AppendData(entity).ExecuteInsertedAsync()).FirstOrDefault();
public void Update(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrows();
public Task UpdateAsync(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrowsAsync();
}
public abstract class BaseRepository : BaseRepository, IRepository
where TEntity : class {
public BaseRepository(IFreeSql fsql) : base(fsql) {
}
public void Delete(TKey id) => _fsql.Delete(id).ExecuteAffrows();
public Task DeleteAsync(TKey id) => _fsql.Delete(id).ExecuteAffrowsAsync();
public TEntity Find(TKey id) => _fsql.Select(id).ToOne();
public Task FindAsync(TKey id) => _fsql.Select(id).ToOneAsync();
public TEntity Get(TKey id) => Find(id);
public Task 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())
.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 {
public SongRepository(IFreeSql fsql) : base(fsql) {
}
}
解释:
至此,通过继承 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