75 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
| using IRaCIS.Core.Domain.Models;
 | |
| using Microsoft.EntityFrameworkCore.Metadata;
 | |
| using Microsoft.EntityFrameworkCore.Metadata.Internal;
 | |
| using System.Reflection;
 | |
| 
 | |
| namespace IRaCIS.Core.Infra.EFCore
 | |
| {
 | |
|     /// <summary>
 | |
|     ///   modelBuilder.Entity<SubjectVisit>().HasQueryFilter(s => !s.IsDeleted);(这个是自动全局配置的)
 | |
|     ///    modelBuilder.Entity<CheckChallengeDialog>().HasQueryFilter(c => !c.SubjectVisit.IsDeleted); (这个没有自动加) 所以有警告
 | |
|     /// </summary>
 | |
|     public static class SoftDeleteQueryExtension
 | |
|     {
 | |
|         public static void AddSoftDeleteQueryFilter(
 | |
|             this IMutableEntityType entityType)
 | |
|         {
 | |
|             var methodToCall = typeof(SoftDeleteQueryExtension)
 | |
|                 .GetMethod(nameof(GetSoftDeleteFilter),
 | |
|                     BindingFlags.NonPublic | BindingFlags.Static)
 | |
|                 .MakeGenericMethod(entityType.ClrType);
 | |
|             var filter = methodToCall.Invoke(null, new object[] { });
 | |
|             entityType.SetQueryFilter((LambdaExpression)filter);
 | |
| 
 | |
|             //foreach (var navigation in entityType.GetNavigations())
 | |
|             //{
 | |
|             //    var targetEntityType = navigation.TargetEntityType;
 | |
| 
 | |
|             //    // 如果目标实体实现了 ISoftDelete 接口,递归添加过滤器
 | |
|             //    if (typeof(ISoftDelete).IsAssignableFrom(targetEntityType.ClrType))
 | |
|             //    {
 | |
|             //        // 在当前实体的导航属性上添加过滤器
 | |
|             //        var targetEntityFilterMethod = typeof(SoftDeleteQueryExtension)
 | |
|             //            .GetMethod(nameof(GetSoftDeleteFilterForNavigation),
 | |
|             //                BindingFlags.NonPublic | BindingFlags.Static)
 | |
|             //            .MakeGenericMethod(entityType.ClrType, targetEntityType.ClrType);
 | |
| 
 | |
|             //        var navigationFilter = targetEntityFilterMethod.Invoke(null, new object[] { navigation });
 | |
|             //        entityType.SetQueryFilter((LambdaExpression)navigationFilter);
 | |
|             //    }
 | |
|             //}
 | |
| 
 | |
| 
 | |
|         }
 | |
| 
 | |
|         private static LambdaExpression GetSoftDeleteFilter<TEntity>()
 | |
|             where TEntity : class, ISoftDelete
 | |
|         {
 | |
|             Expression<Func<TEntity, bool>> filter = x => !x.IsDeleted;
 | |
|             return filter;
 | |
|         }
 | |
| 
 | |
|         // 获取导航属性的软删除过滤器
 | |
|         private static LambdaExpression GetSoftDeleteFilterForNavigation<TEntity, TNavigationEntity>(
 | |
|             IMutableNavigation navigation)
 | |
|             where TEntity : class
 | |
|             where TNavigationEntity : class, ISoftDelete
 | |
|         {
 | |
|             // 获取导航属性的表达式
 | |
|             var parameter = Expression.Parameter(typeof(TEntity), "e");
 | |
|             var navigationExpression = Expression.Property(parameter, navigation.Name);
 | |
| 
 | |
|             // 获取导航属性中的 IsDeleted 属性
 | |
|             var isDeletedProperty = Expression.Property(navigationExpression, nameof(ISoftDelete.IsDeleted));
 | |
| 
 | |
|             // 生成过滤条件:导航属性不为空且未被软删除
 | |
|             var condition = Expression.AndAlso(
 | |
|                 Expression.NotEqual(navigationExpression, Expression.Constant(null, navigationExpression.Type)),  // 判断导航属性是否为null
 | |
|                 Expression.Equal(isDeletedProperty, Expression.Constant(false))  // 判断导航属性的 IsDeleted 为 false
 | |
|             );
 | |
| 
 | |
|             return Expression.Lambda<Func<TEntity, bool>>(condition, parameter);
 | |
|         }
 | |
|     }
 | |
| }
 |