mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-08-02 09:55:57 +08:00
initial commit
This commit is contained in:
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
internal class RepositoryDbContext : DbContext
|
||||
{
|
||||
|
||||
protected IBaseRepository _repo;
|
||||
public RepositoryDbContext(IFreeSql orm, IBaseRepository repo) : base()
|
||||
{
|
||||
_ormScoped = DbContextScopedFreeSql.Create(orm, () => this, () => repo.UnitOfWork);
|
||||
_isUseUnitOfWork = false;
|
||||
UnitOfWork = repo.UnitOfWork;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>> _dicGetRepositoryDbField = new ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>>();
|
||||
static FieldInfo GetRepositoryDbField(Type type, string fieldName) => _dicGetRepositoryDbField.GetOrAdd(type, tp => new ConcurrentDictionary<string, FieldInfo>()).GetOrAdd(fieldName, fn =>
|
||||
typeof(BaseRepository<,>).MakeGenericType(type, typeof(int)).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic));
|
||||
public override IDbSet Set(Type entityType)
|
||||
{
|
||||
if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType];
|
||||
|
||||
var tb = OrmOriginal.CodeFirst.GetTableByEntity(entityType);
|
||||
if (tb == null) return null;
|
||||
|
||||
object repo = _repo;
|
||||
if (entityType != _repo.EntityType)
|
||||
{
|
||||
repo = Activator.CreateInstance(typeof(DefaultRepository<,>).MakeGenericType(entityType, typeof(int)), _repo.Orm);
|
||||
(repo as IBaseRepository).UnitOfWork = _repo.UnitOfWork;
|
||||
GetRepositoryDbField(entityType, "_dbPriv").SetValue(repo, this);
|
||||
GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo,
|
||||
_repo.GetType().GetField("_asTablePriv", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_repo));
|
||||
//GetRepositoryDbField(_repo.EntityType, "_asTablePriv").GetValue(_repo));
|
||||
|
||||
if (typeof(IBaseRepository<>).MakeGenericType(_repo.EntityType).IsAssignableFrom(_repo.GetType()))
|
||||
typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType)
|
||||
.Invoke(null, new object[] { repo, _repo });
|
||||
}
|
||||
|
||||
var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repo) as IDbSet;
|
||||
_listSet.Add(sd);
|
||||
if (entityType != typeof(object)) _dicSet.Add(entityType, sd);
|
||||
return sd;
|
||||
}
|
||||
|
||||
public static void SetRepositoryDataFilter<TEntity>(object repo, IBaseRepository<TEntity> baseRepo) where TEntity : class
|
||||
{
|
||||
var filter = baseRepo.DataFilter as DataFilter<TEntity>;
|
||||
DataFilterUtil.SetRepositoryDataFilter(repo, fl =>
|
||||
{
|
||||
foreach (var f in filter._filters)
|
||||
fl.Apply<TEntity>(f.Key, f.Value.Expression);
|
||||
});
|
||||
}
|
||||
|
||||
int SaveChangesSuccess()
|
||||
{
|
||||
int ret;
|
||||
try
|
||||
{
|
||||
if (UnitOfWork?.EntityChangeReport != null)
|
||||
{
|
||||
UnitOfWork.EntityChangeReport.Report.AddRange(_entityChangeReport);
|
||||
if (UnitOfWork.EntityChangeReport.OnChange == null) UnitOfWork.EntityChangeReport.OnChange = Options.OnEntityChange;
|
||||
} else
|
||||
EmitOnEntityChange(_entityChangeReport);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_entityChangeReport.Clear();
|
||||
ret = _affrows;
|
||||
_affrows = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public override int SaveChanges()
|
||||
{
|
||||
FlushCommand();
|
||||
return SaveChangesSuccess();
|
||||
}
|
||||
#if net40
|
||||
#else
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await FlushCommandAsync(cancellationToken);
|
||||
return SaveChangesSuccess();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
93
FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs
Normal file
93
FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs
Normal file
@ -0,0 +1,93 @@
|
||||
using FreeSql.Extensions.EntityUtil;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
internal class RepositoryDbSet<TEntity> : DbSet<TEntity> where TEntity : class
|
||||
{
|
||||
|
||||
protected BaseRepository<TEntity> _repo;
|
||||
public RepositoryDbSet(BaseRepository<TEntity> repo)
|
||||
{
|
||||
_db = repo._db;
|
||||
_uow = repo.UnitOfWork;
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
IUnitOfWork _uowPriv;
|
||||
internal override IUnitOfWork _uow
|
||||
{
|
||||
get => _uowPriv;
|
||||
set
|
||||
{
|
||||
_uowPriv = value;
|
||||
foreach (var dbset in _dicDbSetObjects.Values) //配合 UnitOfWorkManager
|
||||
dbset._uow = _uowPriv;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ISelect<TEntity> OrmSelect(object dywhere)
|
||||
{
|
||||
var select = base.OrmSelect(dywhere);
|
||||
if (_repo._asTablePriv != null) select.AsTable(_repo._asTablePriv);
|
||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) select.Where(filter.Value.Expression);
|
||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
||||
if (disableFilter.Any()) select.DisableGlobalFilter(disableFilter.ToArray());
|
||||
return select;
|
||||
}
|
||||
internal ISelect<TEntity> OrmSelectInternal(object dywhere) => OrmSelect(dywhere);
|
||||
protected override IUpdate<TEntity> OrmUpdate(IEnumerable<TEntity> entitys)
|
||||
{
|
||||
var update = base.OrmUpdate(entitys);
|
||||
if (_repo._asTablePriv != null) update.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) update.Where(filter.Value.Expression);
|
||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
||||
if (disableFilter.Any()) update.DisableGlobalFilter(disableFilter.ToArray());
|
||||
return update;
|
||||
}
|
||||
internal IUpdate<TEntity> OrmUpdateInternal(IEnumerable<TEntity> entitys) => OrmUpdate(entitys);
|
||||
protected override IDelete<TEntity> OrmDelete(object dywhere)
|
||||
{
|
||||
var delete = base.OrmDelete(dywhere);
|
||||
if (_repo._asTablePriv != null) delete.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) delete.Where(filter.Value.Expression);
|
||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
||||
if (disableFilter.Any()) delete.DisableGlobalFilter(disableFilter.ToArray());
|
||||
return delete;
|
||||
}
|
||||
internal IDelete<TEntity> OrmDeleteInternal(object dywhere) => OrmDelete(dywhere);
|
||||
|
||||
protected override IDelete<object> OrmDeleteAsType(Type entityType)
|
||||
{
|
||||
var delete = base.OrmDeleteAsType(entityType);
|
||||
if (_repo._asTablePriv != null) delete.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||
return delete;
|
||||
}
|
||||
|
||||
protected override IInsert<TEntity> OrmInsert(TEntity entity) => OrmInsert(new[] { entity });
|
||||
protected override IInsert<TEntity> OrmInsert(IEnumerable<TEntity> entitys)
|
||||
{
|
||||
var insert = base.OrmInsert(entitys);
|
||||
if (_repo._asTablePriv != null) insert.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters.Where(a => a.Value.IsEnabled == true);
|
||||
foreach (var filter in filters)
|
||||
{
|
||||
if (entitys != null)
|
||||
foreach (var entity in entitys)
|
||||
if (filter.Value.ExpressionDelegate?.Invoke(entity) == false)
|
||||
throw new Exception(DbContextStrings.InsertError_Filter(filter.Key, filter.Value.Expression, _db.OrmOriginal.GetEntityString(_entityType, entity)));
|
||||
}
|
||||
return insert;
|
||||
}
|
||||
internal IInsert<TEntity> OrmInsertInternal(TEntity entity) => OrmInsert(entity);
|
||||
internal IInsert<TEntity> OrmInsertInternal(IEnumerable<TEntity> entitys) => OrmInsert(entitys);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
|
||||
public interface IRepositoryUnitOfWork : IUnitOfWork
|
||||
{
|
||||
/// <summary>
|
||||
/// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <param name="filter">数据过滤 + 验证</param>
|
||||
/// <returns></returns>
|
||||
IBaseRepository<TEntity, TKey> GetRepository<TEntity, TKey>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class;
|
||||
|
||||
/// <summary>
|
||||
/// 在工作单元内创建联合主键的仓储类,工作单元下的仓储操作具有事务特点
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="filter">数据过滤 + 验证</param>
|
||||
/// <returns></returns>
|
||||
IBaseRepository<TEntity> GetRepository<TEntity>(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>
|
||||
IBaseRepository<TEntity, Guid> 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 IBaseRepository<TEntity, Guid> GetGuidRepository<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<string, string> asTable = null) where TEntity : class
|
||||
{
|
||||
var repo = new GuidRepository<TEntity>(_fsql, filter, asTable);
|
||||
repo.UnitOfWork = this;
|
||||
return repo;
|
||||
}
|
||||
|
||||
public IBaseRepository<TEntity, TKey> GetRepository<TEntity, TKey>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class
|
||||
{
|
||||
var repo = new DefaultRepository<TEntity, TKey>(_fsql, filter);
|
||||
repo.UnitOfWork = this;
|
||||
return repo;
|
||||
}
|
||||
|
||||
public IBaseRepository<TEntity> GetRepository<TEntity>(Expression<Func<TEntity, bool>> filter = null) where TEntity : class
|
||||
{
|
||||
var repo = new DefaultRepository<TEntity, int>(_fsql, filter);
|
||||
repo.UnitOfWork = this;
|
||||
return repo;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user