mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-19 01:12:49 +08:00
97 lines
4.0 KiB
C#
97 lines
4.0 KiB
C#
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
|
|
}
|
|
}
|