mirror of
https://github.com/cq-panda/Vue.NetCore.git
synced 2026-10-18 22:46:05 +08:00
369 lines
15 KiB
C#
Executable File
369 lines
15 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using VOL.Core.EFDbContext;
|
|
using VOL.Core.Enums;
|
|
using VOL.Core.Extensions;
|
|
using VOL.Entity;
|
|
|
|
namespace VOL.Core.BaseProvider
|
|
{
|
|
public static class ApplicationServiceBaseDeleteExtensions
|
|
{
|
|
private static MethodInfo[] Methods
|
|
{
|
|
get
|
|
{
|
|
return typeof(ApplicationServiceBaseDeleteExtensions)
|
|
.GetMethods(BindingFlags.Public | BindingFlags.Static);
|
|
}
|
|
}
|
|
public static int DeleteWithType(this BaseDbContext dbContext, Type entityType, List<object> keys, PropertyInfo keyPro = null, bool logicDel = true)
|
|
{
|
|
if (keys == null || keys.Count == 0) return 0;
|
|
int delCount = 0;
|
|
keyPro ??= entityType.GetKeyProperty();
|
|
|
|
var logicDelProperty = entityType.GetLogicDelPropertyWithType();
|
|
|
|
if (logicDel && logicDelProperty != null)
|
|
{
|
|
delCount = Methods.First(m => m.Name == nameof(LogicDelete))
|
|
.MakeGenericMethod(entityType, keyPro.PropertyType, logicDelProperty.PropertyType)
|
|
.Invoke(null, [dbContext, keys, keyPro.Name, logicDelProperty]).GetInt();
|
|
}
|
|
else
|
|
{
|
|
delCount = Methods.First(m => m.Name == nameof(Delete))
|
|
.MakeGenericMethod(entityType, keyPro.PropertyType)
|
|
.Invoke(null, [dbContext, keys, keyPro.Name]).GetInt();
|
|
}
|
|
return delCount;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="entityType"></param>
|
|
/// <param name="keys"></param>
|
|
/// <param name="keyPro"></param>
|
|
/// <param name="logicDel"></param>
|
|
/// <returns></returns>
|
|
public static async Task<int> DeleteWithTypeAsync(this BaseDbContext dbContext,
|
|
Type entityType,
|
|
List<object> keys,
|
|
PropertyInfo keyPro = null,
|
|
bool logicDel = true)
|
|
{
|
|
if (keys == null || keys.Count == 0) return 0;
|
|
int delCount = 0;
|
|
keyPro ??= entityType.GetKeyProperty();
|
|
|
|
var logicDelProperty = entityType.GetLogicDelPropertyWithType();
|
|
if (logicDel && logicDelProperty != null)
|
|
{
|
|
delCount = await (Methods
|
|
.First(m => m.Name == nameof(LogicDeleteAsync))
|
|
.MakeGenericMethod(entityType, keyPro.PropertyType, logicDelProperty.PropertyType)
|
|
.Invoke(null, [dbContext, keys, keyPro.Name, logicDelProperty]) as Task<int>);
|
|
}
|
|
else
|
|
{
|
|
delCount = await (Methods
|
|
.First(m => m.Name == nameof(DeleteAsync))
|
|
.MakeGenericMethod(entityType, keyPro.PropertyType)
|
|
.Invoke(null, [dbContext, keys, keyPro.Name]) as Task<int>);
|
|
}
|
|
return delCount;
|
|
}
|
|
/// <summary>
|
|
/// 删除二、三级明细表
|
|
/// </summary>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="entityType"></param>
|
|
/// <param name="keyList"></param>
|
|
/// <returns></returns>
|
|
public static async Task<int> DeleteAllDetilWithTypeAsync(this BaseDbContext dbContext, Type entityType, List<object> keyList)
|
|
{
|
|
int delCount = 0;
|
|
if (keyList.Count == 0)
|
|
{
|
|
return delCount;
|
|
}
|
|
var detailTypes = entityType.GetCustomAttribute<EntityAttribute>()?.DetailTable ?? [];
|
|
if (detailTypes.Length == 0) return delCount;
|
|
|
|
foreach (var detailType in detailTypes)
|
|
{
|
|
//删除三级明细表
|
|
var detailFkToMain = entityType.GetForeignKeyType(detailType, detailType.Name);
|
|
var subTypes = detailType.GetCustomAttribute<EntityAttribute>()?.DetailTable ?? [];
|
|
if (subTypes.Length > 0)
|
|
{
|
|
var detailKeyPro = detailType.GetKeyProperty();
|
|
var detailKeys = await dbContext.QueryKeysByForeignKeysAsync(detailType, detailKeyPro, detailFkToMain, keyList);
|
|
if (detailKeys.Count > 0)
|
|
{
|
|
foreach (var subType in subTypes)
|
|
{
|
|
var subFkToDetail = detailType.GetForeignKeyType(subType, subType.Name);
|
|
await dbContext.DeleteWithTypeAsync(subType, detailKeys, subFkToDetail, true);
|
|
}
|
|
}
|
|
}
|
|
//删除二级明细表
|
|
delCount += await dbContext.DeleteWithTypeAsync(detailType, keyList, detailFkToMain, true);
|
|
}
|
|
return delCount;
|
|
}
|
|
|
|
public static int DeleteAllDetilWithType(this BaseDbContext dbContext, Type entityType, List<object> keyList)
|
|
{
|
|
int delCount = 0;
|
|
if (keyList.Count == 0)
|
|
{
|
|
return delCount;
|
|
}
|
|
var detailTypes = entityType.GetCustomAttribute<EntityAttribute>()?.DetailTable ?? [];
|
|
if (detailTypes.Length == 0) return delCount;
|
|
|
|
foreach (var detailType in detailTypes)
|
|
{
|
|
//删除三级明细表
|
|
var detailFkToMain = entityType.GetForeignKeyType(detailType, detailType.Name);
|
|
var subTypes = detailType.GetCustomAttribute<EntityAttribute>()?.DetailTable ?? [];
|
|
if (subTypes.Length > 0)
|
|
{
|
|
var detailKeyPro = detailType.GetKeyProperty();
|
|
var detailKeys = dbContext.QueryKeysByForeignKeys(detailType, detailKeyPro, detailFkToMain, keyList);
|
|
if (detailKeys.Count > 0)
|
|
{
|
|
foreach (var subType in subTypes)
|
|
{
|
|
var subFkToDetail = detailType.GetForeignKeyType(subType, subType.Name);
|
|
dbContext.DeleteWithType(subType, detailKeys, subFkToDetail, true);
|
|
}
|
|
}
|
|
}
|
|
//删除二级明细表
|
|
delCount += dbContext.DeleteWithType(detailType, keyList, detailFkToMain, true);
|
|
}
|
|
return delCount;
|
|
}
|
|
|
|
public static int Delete<TEntity, TKey>(this BaseDbContext dbContext, List<object> keys, string keyName)
|
|
where TEntity : class
|
|
{
|
|
var expression = CreateExpression<TEntity, TKey>(keyName, keys);
|
|
if (expression == null) return 0;
|
|
return dbContext.Set<TEntity>().Where(expression).ExecuteDelete();
|
|
}
|
|
|
|
public static async Task<int> DeleteAsync<TEntity, TKey>(this BaseDbContext dbContext, List<object> keys, string keyName)
|
|
where TEntity : class
|
|
{
|
|
var expression = CreateExpression<TEntity, TKey>(keyName, keys);
|
|
if (expression == null) return 0;
|
|
return await dbContext.Set<TEntity>().Where(expression).ExecuteDeleteAsync();
|
|
}
|
|
private static Expression<Func<TEntity, bool>> CreateExpression<TEntity, TKey>(string keyName, List<object> keys)
|
|
where TEntity : class
|
|
{
|
|
if (keys == null) return null;
|
|
var values = keys.Where(k => k != null).Select(k => (TKey)k.ChangeType(typeof(TKey))).ToList();
|
|
if (values.Count == 0) return null;
|
|
return keyName.CreateExpression<TEntity>(values, LinqExpressionType.In);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 逻辑删除
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="keys"></param>
|
|
/// <param name="keyName"></param>
|
|
/// <returns></returns>
|
|
public static int LogicDelete<TEntity, TKey, LogicFieldType>(this BaseDbContext dbContext,
|
|
List<object> keys,
|
|
string keyName,
|
|
PropertyInfo logicDelProperty)
|
|
where TEntity : class
|
|
{
|
|
var expression = CreateExpression<TEntity, TKey>(keyName, keys);
|
|
if (expression == null) return 0;
|
|
var value = (LogicFieldType)(((int)DelStatus.已删除).ChangeType(typeof(LogicFieldType)));
|
|
dbContext
|
|
.Set<TEntity>()
|
|
.Where(expression)
|
|
.ExecuteUpdate(c => c.SetProperty(e => EF.Property<LogicFieldType>(e, logicDelProperty.Name),
|
|
value));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// ??潩
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TKey"></typeparam>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="keys"></param>
|
|
/// <param name="keyName"></param>
|
|
/// <returns></returns>
|
|
public static async Task<int> LogicDeleteAsync<TEntity, TKey, LogicFieldType>(this BaseDbContext dbContext,
|
|
List<object> keys,
|
|
string keyName,
|
|
PropertyInfo logicDelProperty)
|
|
where TEntity : class
|
|
{
|
|
var expression = CreateExpression<TEntity, TKey>(keyName, keys);
|
|
if (expression == null) return 0;
|
|
var value = (LogicFieldType)(((int)DelStatus.已删除).ChangeType(typeof(LogicFieldType)));
|
|
await dbContext
|
|
.Set<TEntity>()
|
|
.Where(expression)
|
|
.ExecuteUpdateAsync(c => c.SetProperty(e => EF.Property<LogicFieldType>(e, logicDelProperty.Name),
|
|
value));
|
|
return 0;
|
|
}
|
|
|
|
|
|
public static async Task<List<object>> QueryKeysByForeignKeysAsync(
|
|
this BaseDbContext dbContext,
|
|
Type entityType,
|
|
PropertyInfo selectKeyProperty,
|
|
PropertyInfo whereForeignKeyProperty,
|
|
List<object> foreignKeyValues)
|
|
{
|
|
var method = typeof(ApplicationServiceBaseDeleteExtensions)
|
|
.GetMethod(nameof(QueryKeysByForeignKeysCore), BindingFlags.NonPublic | BindingFlags.Static);
|
|
|
|
var generic = method.MakeGenericMethod(entityType, whereForeignKeyProperty.PropertyType, selectKeyProperty.PropertyType);
|
|
var query = generic.Invoke(null,
|
|
[
|
|
dbContext,
|
|
whereForeignKeyProperty.Name,
|
|
foreignKeyValues,
|
|
selectKeyProperty.Name
|
|
]) as IQueryable<object>;
|
|
return await query.ToListAsync();
|
|
}
|
|
|
|
public static List<object> QueryKeysByForeignKeys(
|
|
this BaseDbContext dbContext,
|
|
Type entityType,
|
|
PropertyInfo selectKeyProperty,
|
|
PropertyInfo whereForeignKeyProperty,
|
|
List<object> foreignKeyValues)
|
|
{
|
|
var method = typeof(ApplicationServiceBaseDeleteExtensions)
|
|
.GetMethod(nameof(QueryKeysByForeignKeysCore), BindingFlags.NonPublic | BindingFlags.Static);
|
|
|
|
var generic = method.MakeGenericMethod(entityType, whereForeignKeyProperty.PropertyType, selectKeyProperty.PropertyType);
|
|
var query = generic.Invoke(null,
|
|
[
|
|
dbContext,
|
|
whereForeignKeyProperty.Name,
|
|
foreignKeyValues,
|
|
selectKeyProperty.Name
|
|
]) as IQueryable<object>;
|
|
return query.ToList();
|
|
}
|
|
|
|
private static IQueryable<object> QueryKeysByForeignKeysCore<TQueryEntity, TWhereKey, TSelectKey>(
|
|
BaseDbContext dbContext,
|
|
string whereForeignKeyName,
|
|
List<object> foreignKeyValues,
|
|
string selectKeyName)
|
|
where TQueryEntity : class
|
|
{
|
|
var values = foreignKeyValues
|
|
.Where(k => k != null)
|
|
.Select(k => (TWhereKey)k.ChangeType(typeof(TWhereKey)))
|
|
.ToList();
|
|
var predicate = whereForeignKeyName.CreateExpression<TQueryEntity>(values, LinqExpressionType.In);
|
|
return dbContext.Set<TQueryEntity>()
|
|
.Where(predicate)
|
|
.Select(e => EF.Property<TSelectKey>(e, selectKeyName))
|
|
.Select(v => (object)v);
|
|
}
|
|
/// <summary>
|
|
/// 获取删除前的原始数据
|
|
/// </summary>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <param name="dbContext"></param>
|
|
/// <param name="keyList"></param>
|
|
/// <returns></returns>
|
|
public static List<TEntity> QueryOriginListByKeys<TEntity>(
|
|
this BaseDbContext dbContext,
|
|
List<object> keyList,
|
|
bool checkActionLog = true)
|
|
where TEntity : class
|
|
{
|
|
if (keyList == null || keyList.Count == 0) return [];
|
|
if (checkActionLog)
|
|
{
|
|
//没有审计日志的不记录
|
|
bool isActionLog = typeof(TEntity).IsTableActionLog();
|
|
if (!isActionLog) return null;
|
|
}
|
|
var keyPro = typeof(TEntity).GetKeyProperty();
|
|
var method = typeof(ApplicationServiceBaseDeleteExtensions)
|
|
.GetMethod(nameof(QueryOriginListByKeysCoreAsync), BindingFlags.NonPublic | BindingFlags.Static);
|
|
var generic = method.MakeGenericMethod(typeof(TEntity), keyPro.PropertyType);
|
|
var query = generic.Invoke(null,
|
|
[
|
|
dbContext,
|
|
keyPro.Name,
|
|
keyList
|
|
]) as IQueryable<TEntity>;
|
|
return query.ToList();
|
|
}
|
|
|
|
public static async Task<List<TEntity>> QueryOriginListByKeysAsync<TEntity>(
|
|
this BaseDbContext dbContext,
|
|
List<object> keyList,
|
|
bool checkActionLog = true)
|
|
where TEntity : class
|
|
{
|
|
if (keyList == null || keyList.Count == 0) return [];
|
|
if (checkActionLog)
|
|
{
|
|
//没有审计日志的不记录
|
|
bool isActionLog = typeof(TEntity).IsTableActionLog();
|
|
if (!isActionLog) return null;
|
|
}
|
|
var keyPro = typeof(TEntity).GetKeyProperty();
|
|
var method = typeof(ApplicationServiceBaseDeleteExtensions)
|
|
.GetMethod(nameof(QueryOriginListByKeysCoreAsync), BindingFlags.NonPublic | BindingFlags.Static);
|
|
var generic = method.MakeGenericMethod(typeof(TEntity), keyPro.PropertyType);
|
|
var query = generic.Invoke(null,
|
|
[
|
|
dbContext,
|
|
keyPro.Name,
|
|
keyList
|
|
]) as IQueryable<TEntity>;
|
|
return await query.ToListAsync();
|
|
}
|
|
|
|
private static IQueryable<TEntity> QueryOriginListByKeysCoreAsync<TEntity, TKey>(
|
|
BaseDbContext dbContext,
|
|
string keyName,
|
|
List<object> keyList)
|
|
where TEntity : class
|
|
{
|
|
var values = keyList
|
|
.Where(k => k != null)
|
|
.Select(k => (TKey)k.ChangeType(typeof(TKey)))
|
|
.ToList();
|
|
var predicate = keyName.CreateExpression<TEntity>(values, LinqExpressionType.In);
|
|
return dbContext.Set<TEntity>().Where(predicate);
|
|
}
|
|
|
|
}
|
|
} |