FreeSql.DbContext 融合 Repository + UnitOfWork

This commit is contained in:
28810
2019-03-30 19:11:17 +08:00
parent 496750da94
commit a7e06843a9
15 changed files with 222 additions and 264 deletions

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FreeSql {
internal class RepositoryDbContext<TEntity> : DbContext where TEntity : class {
protected BaseRepository<TEntity> _repos;
public RepositoryDbContext(IFreeSql orm, BaseRepository<TEntity> repos) : base() {
_orm = orm;
_repos = repos;
_isUseUnitOfWork = false;
}
public override object Set(Type entityType) {
if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType];
var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), _repos);
_dicSet.Add(entityType, sd);
return sd;
}
RepositoryDbSet<TEntity> _dbSet;
public RepositoryDbSet<TEntity> DbSet => _dbSet ?? (_dbSet = Set<TEntity>() as RepositoryDbSet<TEntity>);
}
}

View File

@ -9,8 +9,9 @@ namespace FreeSql {
protected BaseRepository<TEntity> _repos;
public RepositoryDbSet(BaseRepository<TEntity> repos) {
_ctx = repos._db;
_fsql = repos._fsql;
_uow = repos._uow;
_uow = repos.UnitOfWork;
_repos = repos;
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace FreeSql {
public interface IRepositoryUnitOfWork : IUnitOfWork {
/// <summary>
/// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="filter">数据过滤 + 验证</param>
/// <returns></returns>
DefaultRepository<TEntity, TKey> GetRepository<TEntity, TKey>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class;
/// <summary>
/// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="filter">数据过滤 + 验证</param>
/// <param name="asTable">分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository</param>
/// <returns></returns>
GuidRepository<TEntity> GetGuidRepository<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<string, string> asTable = null) where TEntity : class;
}
class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork {
public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) {
}
public GuidRepository<TEntity> GetGuidRepository<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<string, string> asTable = null) where TEntity : class {
var repos = new GuidRepository<TEntity>(_fsql, filter, asTable);
repos.UnitOfWork = this;
return repos;
}
public DefaultRepository<TEntity, TKey> GetRepository<TEntity, TKey>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class {
var repos = new DefaultRepository<TEntity, TKey>(_fsql, filter);
repos.UnitOfWork = this;
return repos;
}
}
}

View File

@ -22,7 +22,7 @@ public static class FreeSqlRepositoryExtenssions {
}
/// <summary>
/// 返回仓库类,适用 Insert 方法无须返回插入的数据
/// 返回仓库类
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="that"></param>

View File

@ -11,9 +11,7 @@ namespace FreeSql {
where TEntity : class {
internal IFreeSql _fsql;
internal UnitOfWork _uow;
RepositoryDbSet<TEntity> _setPriv;
internal RepositoryDbSet<TEntity> _set => _setPriv ?? (_setPriv = new RepositoryDbSet<TEntity>(this));
internal RepositoryDbContext<TEntity> _db;
public IDataFilter<TEntity> DataFilter { get; } = new DataFilter<TEntity>();
Func<string, string> _asTableVal;
protected Func<string, string> AsTable {
@ -32,45 +30,89 @@ namespace FreeSql {
DataFilterUtil.SetRepositoryDataFilter(this, null);
DataFilter.Apply("", filter);
AsTable = asTable;
_db = new RepositoryDbContext<TEntity>(_fsql, this);
}
public Type EntityType => _set._entityTypeInternal;
public IUpdate<TEntity> UpdateDiy => _set.OrmUpdateInternal(null);
~BaseRepository() {
this.Dispose();
}
bool _isdisposed = false;
public void Dispose() {
if (_isdisposed) return;
try {
_db.Dispose();
this.DataFilter.Dispose();
} finally {
_isdisposed = true;
GC.SuppressFinalize(this);
}
}
public IUnitOfWork UnitOfWork { get; set; }
public Type EntityType => _db.DbSet._entityTypeInternal;
public IUpdate<TEntity> UpdateDiy => _db.DbSet.OrmUpdateInternal(null);
public ISelect<TEntity> Select => _set.OrmSelectInternal(null);
public ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp) => _set.OrmSelectInternal(null).Where(exp);
public ISelect<TEntity> WhereIf(bool condition, Expression<Func<TEntity, bool>> exp) => _set.OrmSelectInternal(null).WhereIf(condition, exp);
public ISelect<TEntity> Select => _db.DbSet.OrmSelectInternal(null);
public ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp) => _db.DbSet.OrmSelectInternal(null).Where(exp);
public ISelect<TEntity> WhereIf(bool condition, Expression<Func<TEntity, bool>> exp) => _db.DbSet.OrmSelectInternal(null).WhereIf(condition, exp);
public int Delete(Expression<Func<TEntity, bool>> predicate) => _set.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows();
public Task<int> DeleteAsync(Expression<Func<TEntity, bool>> predicate) => _set.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync();
public int Delete(Expression<Func<TEntity, bool>> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows();
public Task<int> DeleteAsync(Expression<Func<TEntity, bool>> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync();
public int Delete(TEntity entity) => _set.RemoveAffrows(entity);
public Task<int> DeleteAsync(TEntity entity) => _set.RemoveAffrowsAsync(entity);
public int Delete(IEnumerable<TEntity> entitys) => _set.RemoveRangeAffrows(entitys);
public Task<int> DeleteAsync(IEnumerable<TEntity> entitys) => _set.RemoveRangeAffrowsAsync(entitys);
public int Delete(TEntity entity) {
_db.DbSet.Remove(entity);
return _db.SaveChanges();
}
public Task<int> DeleteAsync(TEntity entity) {
_db.DbSet.Remove(entity);
return _db.SaveChangesAsync();
}
public int Delete(IEnumerable<TEntity> entitys) {
_db.DbSet.RemoveRange(entitys);
return _db.SaveChanges();
}
public Task<int> DeleteAsync(IEnumerable<TEntity> entitys) {
_db.DbSet.RemoveRange(entitys);
return _db.SaveChangesAsync();
}
public virtual TEntity Insert(TEntity entity) {
_set.Add(entity);
_db.DbSet.Add(entity);
_db.SaveChanges();
return entity;
}
async public virtual Task<TEntity> InsertAsync(TEntity entity) {
await _db.DbSet.AddAsync(entity);
_db.SaveChanges();
return entity;
}
public virtual List<TEntity> Insert(IEnumerable<TEntity> entitys) {
_set.AddRange(entitys);
_db.DbSet.AddRange(entitys);
_db.SaveChanges();
return entitys.ToList();
}
async public virtual Task<TEntity> InsertAsync(TEntity entity) {
await _set.AddAsync(entity);
return entity;
}
async public virtual Task<List<TEntity>> InsertAsync(IEnumerable<TEntity> entitys) {
await _set.AddRangeAsync(entitys);
await _db.DbSet.AddRangeAsync(entitys);
await _db.SaveChangesAsync();
return entitys.ToList();
}
public int Update(TEntity entity) => _set.UpdateAffrows(entity);
public Task<int> UpdateAsync(TEntity entity) => _set.UpdateAffrowsAsync(entity);
public int Update(IEnumerable<TEntity> entitys) => _set.UpdateRangeAffrows(entitys);
public Task<int> UpdateAsync(IEnumerable<TEntity> entitys) => _set.UpdateRangeAffrowsAsync(entitys);
public int Update(TEntity entity) {
_db.DbSet.Update(entity);
return _db.SaveChanges();
}
public Task<int> UpdateAsync(TEntity entity) {
_db.DbSet.Update(entity);
return _db.SaveChangesAsync();
}
public int Update(IEnumerable<TEntity> entitys) {
_db.DbSet.UpdateRange(entitys);
return _db.SaveChanges();
}
public Task<int> UpdateAsync(IEnumerable<TEntity> entitys) {
_db.DbSet.UpdateRange(entitys);
return _db.SaveChangesAsync();
}
}
public abstract class BaseRepository<TEntity, TKey> : BaseRepository<TEntity>, IRepository<TEntity, TKey>
@ -81,17 +123,19 @@ namespace FreeSql {
public int Delete(TKey id) {
var stateKey = string.Concat(id);
if (_set._statesInternal.ContainsKey(stateKey)) _set._statesInternal.Remove(stateKey);
return _set.OrmDeleteInternal(id).ExecuteAffrows();
if (_db.DbSet._statesInternal.ContainsKey(stateKey))
_db.DbSet._statesInternal.Remove(stateKey);
return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrows();
}
public Task<int> DeleteAsync(TKey id) {
var stateKey = string.Concat(id);
if (_set._statesInternal.ContainsKey(stateKey)) _set._statesInternal.Remove(stateKey);
return _set.OrmDeleteInternal(id).ExecuteAffrowsAsync();
if (_db.DbSet._statesInternal.ContainsKey(stateKey))
_db.DbSet._statesInternal.Remove(stateKey);
return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrowsAsync();
}
public TEntity Find(TKey id) => _set.OrmSelectInternal(id).ToOne();
public Task<TEntity> FindAsync(TKey id) => _set.OrmSelectInternal(id).ToOneAsync();
public TEntity Find(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOne();
public Task<TEntity> FindAsync(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOneAsync();
public TEntity Get(TKey id) => Find(id);
public Task<TEntity> GetAsync(TKey id) => FindAsync(id);

View File

@ -4,8 +4,9 @@ using System.Threading.Tasks;
namespace FreeSql {
public interface IRepository {
public interface IRepository : IDisposable {
Type EntityType { get; }
IUnitOfWork UnitOfWork { get; set; }
}
public interface IRepository<TEntity> : IReadOnlyRepository<TEntity>, IBasicRepository<TEntity>

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace FreeSql {
class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork {
public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) {
}
public GuidRepository<TEntity> GetGuidRepository<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<string, string> asTable = null) where TEntity : class {
var repos = new GuidRepository<TEntity>(_fsql, filter, asTable);
repos._uow = this;
return repos;
}
public DefaultRepository<TEntity, TKey> GetRepository<TEntity, TKey>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class {
var repos = new DefaultRepository<TEntity, TKey>(_fsql, filter);
repos._uow = this;
return repos;
}
}
}