using EFCore.BulkExtensions;
|
using Furion.DatabaseAccessor;
|
using Furion.DistributedIDGenerator;
|
using Furion.FriendlyException;
|
using Mapster;
|
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
using Microsoft.EntityFrameworkCore.Storage;
|
using System;
|
using System.Collections.Generic;
|
using System.Data.Common;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
|
namespace ApiTools.Core
|
{
|
public abstract class BaseRepository<TEntity, TDbContextLocator>
|
where TEntity : CommonEntity, new()
|
where TDbContextLocator : class, IDbContextLocator
|
{
|
public readonly IRepository<TEntity, TDbContextLocator> rep;
|
public readonly CurrentLogier logier;
|
|
public BaseRepository(
|
IRepository<TEntity, TDbContextLocator> rep)
|
{
|
this.rep = rep;
|
logier = JwtUtils.GetCurrentLogier();
|
}
|
|
public virtual IQueryable<TEntity> GetQueryableIgnoreFilter(bool noTracking = true)
|
{
|
return rep.GetQueryable(noTracking);
|
}
|
|
/// <summary>
|
/// 获取查询
|
/// </summary>
|
/// <param name="noTracking"></param>
|
/// <returns></returns>
|
public virtual IQueryable<TEntity> GetQueryable(bool noTracking = true)
|
{
|
return rep.GetQueryable(noTracking);
|
}
|
|
/// <summary>
|
/// 获取查询
|
/// </summary>
|
/// <param name="noTracking"></param>
|
/// <param name="query"></param>
|
/// <returns></returns>
|
public virtual IQueryable<TEntity> GetQueryable(
|
bool noTracking,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query)
|
{
|
var q = GetQueryable(false);
|
if (query != null)
|
{
|
q = query(q);
|
}
|
return q;
|
}
|
|
/// <summary>
|
/// 获取实体
|
/// </summary>
|
/// <param name="id"></param>
|
/// <param name="query"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public virtual Task<TEntity> Get(
|
Guid id,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
return GetQueryable(false, query)
|
.Where(it => it.Id == id)
|
.FirstOrDefaultAsync(cancellationToken);
|
}
|
|
/// <summary>
|
/// 获取实体
|
/// </summary>
|
/// <param name="ids"></param>
|
/// <param name="query"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public virtual Task<List<TEntity>> Get(
|
List<Guid> ids,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
return GetQueryable(false, query)
|
.Where(it => ids.Contains(it.Id))
|
.ToListAsync(cancellationToken);
|
}
|
|
/// <summary>
|
/// 查询选择器数据
|
/// </summary>
|
/// <typeparam name="TValue"></typeparam>
|
/// <typeparam name="TData"></typeparam>
|
/// <param name="request"></param>
|
/// <param name="getValue"></param>
|
/// <param name="getLabel"></param>
|
/// <param name="query"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<List<SelectOption<TValue, TData>>> GetSelect<TValue, TData>(
|
SelectQuery<TValue, TData> request,
|
Func<TData, TValue> getValue,
|
Func<TData, string> getLabel,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
var q = GetQueryable();
|
if (query != null) q = query(q);
|
else q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime);
|
var models = await q
|
.ProjectToType<TData>()
|
.ToListAsync(cancellationToken);
|
var options = new List<SelectOption<TValue, TData>>();
|
foreach (var model in models)
|
{
|
var option = new SelectOption<TValue, TData>();
|
option.Data = model;
|
option.Value = getValue(model);
|
option.Label = getLabel(model);
|
options.Add(option);
|
}
|
return options;
|
}
|
|
public async Task<TResult> GetDetail<TResult>(
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
var model = await GetQueryable(false, query)
|
.ProjectToType<TResult>()
|
.FirstOrDefaultAsync(cancellationToken);
|
if (model == null)
|
{
|
var summary = await typeof(TEntity).GetSummary();
|
throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}");
|
}
|
return model;
|
}
|
|
/// <summary>
|
/// 设置是否禁用
|
/// </summary>
|
/// <param name="request"></param>
|
/// <param name="query"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<int> SetIsDisabled(
|
SetIsDisabledCommand request,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
var q = GetQueryable(false);
|
if (query != null) q = query(q);
|
var entities = await q
|
.Where(it => request.Ids.Contains(it.Id))
|
.ToListAsync();
|
var isDisabledProperty = typeof(TEntity).GetProperty("IsDisabled", typeof(bool));
|
foreach (var entity in entities)
|
{
|
isDisabledProperty.SetValue(entity, request.IsDisabled);
|
}
|
await UpdateAsync(entities);
|
return entities.Count;
|
}
|
|
/// <summary>
|
/// 删除数据
|
/// </summary>
|
/// <param name="request"></param>
|
/// <param name="query"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<int> DeleteData(
|
DeleteDataCommand request, Func<IQueryable<TEntity>,
|
IQueryable<TEntity>> query = null,
|
CancellationToken cancellationToken = default)
|
{
|
var q = GetQueryable(false);
|
if (query != null) q = query(q);
|
var entities = await q
|
.Where(it => request.Ids.Contains(it.Id))
|
.ToListAsync(cancellationToken);
|
return entities.Any()
|
? await rep.DeleteNowAsync(entities, cancellationToken)
|
: 0;
|
}
|
|
/// <summary>
|
/// 更新数据
|
/// </summary>
|
/// <typeparam name="TRequest"></typeparam>
|
/// <param name="q"></param>
|
/// <param name="request"></param>
|
/// <param name="update"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<Guid> UpdateData<TRequest>(
|
IQueryable<TEntity> q,
|
TRequest request,
|
Action<TEntity> update = null,
|
CancellationToken cancellationToken = default)
|
{
|
var entity = await q.FirstOrDefaultAsync();
|
if (entity == null)
|
{
|
var summary = await typeof(TEntity).GetSummary();
|
throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}");
|
}
|
|
if (update != null) update(entity);
|
else request.Adapt(entity);
|
await rep.UpdateAsync(entity);
|
return entity.Id;
|
}
|
|
/// <summary>
|
/// 保存数据
|
/// </summary>
|
/// <typeparam name="TRequest"></typeparam>
|
/// <param name="request"></param>
|
/// <param name="query"></param>
|
/// <param name="checkExist"></param>
|
/// <param name="update"></param>
|
/// <param name="cancellationToken"></param>
|
/// <returns></returns>
|
public async Task<TEntity> SaveData<TRequest>(
|
TRequest request,
|
Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null,
|
Expression<Func<TEntity, bool>> checkExist = null,
|
Action<TEntity> update = null,
|
CancellationToken cancellationToken = default)
|
where TRequest : SaveDataCommand, new()
|
{
|
var xmlDoc = await XmlDocUtils.GetXmlDocAsync();
|
var summary = await typeof(TEntity).GetSummary(xmlDoc);
|
if (checkExist != null && await GetQueryableIgnoreFilter().AnyAsync(checkExist))
|
throw Oops.Oh(EnumErrorCodeType.s405, $"{summary ?? "信息"}");
|
if (request.Id.HasValue)
|
{
|
var q = GetQueryable(false);
|
if (query != null) q = query(q);
|
var entity = await q.FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
|
if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, $"{summary ?? "信息"}");
|
if (update != null) update(entity);
|
else request.Adapt(entity);
|
await rep.UpdateAsync(entity);
|
return entity;
|
}
|
else
|
{
|
var entity = new TEntity();
|
if (update != null) update(entity);
|
else request.Adapt(entity);
|
await rep.InsertAsync(entity);
|
return entity;
|
}
|
}
|
|
public virtual Task<List<T1>> SqlQueriesAsync<T1>(string sql, object model, CancellationToken cancellationToken = default)
|
{
|
return rep.SqlQueriesAsync<T1>(sql, model, cancellationToken);
|
}
|
|
public virtual IDbContextTransaction BeginTransaction()
|
{
|
return rep.Database.BeginTransaction();
|
}
|
|
public virtual Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default)
|
{
|
return rep.InsertAsync(entity, cancellationToken: cancellationToken);
|
}
|
|
public virtual Task InsertNowAsync(TEntity entity, CancellationToken cancellationToken = default)
|
{
|
return rep.InsertNowAsync(entity, cancellationToken: cancellationToken);
|
}
|
|
public virtual Task InsertAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
|
{
|
return rep.InsertAsync(entities, cancellationToken);
|
}
|
|
public virtual Task<int> InsertNowAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
|
{
|
return rep.InsertNowAsync(entities, cancellationToken);
|
}
|
|
public virtual async Task BulkInsertAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
|
{
|
await rep.Context.BulkInsertAsync(entities, cancellationToken: cancellationToken);
|
}
|
|
public virtual Task UpdateAsync(TEntity entity)
|
{
|
return rep.UpdateAsync(entity);
|
}
|
|
public virtual Task UpdateNowAsync(TEntity entity)
|
{
|
return rep.UpdateNowAsync(entity);
|
}
|
|
public virtual Task UpdateAsync(List<TEntity> entities)
|
{
|
return rep.UpdateAsync(entities);
|
}
|
|
public virtual Task<int> UpdateNowAsync(List<TEntity> entities)
|
{
|
return rep.UpdateNowAsync(entities);
|
}
|
|
public virtual Task DeleteAsync(TEntity entity)
|
{
|
return rep.DeleteAsync(entity);
|
}
|
|
public virtual Task DeleteNowAsync(TEntity entity, CancellationToken cancellationToken = default)
|
{
|
return rep.DeleteNowAsync(entity, cancellationToken);
|
}
|
|
public virtual Task DeleteAsync(List<TEntity> entities)
|
{
|
return rep.DeleteAsync(entities);
|
}
|
|
public virtual Task<int> DeleteNowAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
|
{
|
return rep.DeleteNowAsync(entities, cancellationToken);
|
}
|
|
public virtual Task SaveNowAsync()
|
{
|
return rep.SaveNowAsync();
|
}
|
}
|
}
|