using Microsoft.Extensions.DependencyInjection; using SqlSugar; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Wood.Util; namespace WoodWood.Util.Validations { /// /// 数据库中 唯一值验证 /// null 和 "" 不会进行验证 /// public class UniqueValueAttribute : ValidationAttribute { /// /// 字段名称,留空取当前 /// public string? PropertyName { get; set; } /// /// 实体,留空取当前 /// public Type? EntityType { get; set; } /// /// /// /// /// /// protected override ValidationResult IsValid(object? value, ValidationContext validationContext) { if (value == null|| string.IsNullOrEmpty(value.ToString())) return ValidationResult.Success!; var serviceProvider = validationContext.GetService(typeof(IServiceProvider)) as IServiceProvider; if (serviceProvider == null) return new ValidationResult($"[{validationContext.MemberName}]无法获取服务提供者!"); // 获取 ISqlSugarClient 实例 var sqlClient = serviceProvider!.GetRequiredService(); if (sqlClient == null) return new ValidationResult($"[{validationContext.MemberName}]无法获取 ISqlSugarClient!"); string sqlTable = ""; bool hasTenantFilter = false; bool hasDeletedFilter = false; string sqlProperty = ""; Type sqlPropertyType; //字段名 if (string.IsNullOrEmpty(PropertyName)) // 获取成员名称(属性名) sqlProperty = validationContext.MemberName ?? ""; else sqlProperty = PropertyName; Type sqlType; //表明 if (EntityType == null) sqlType = validationContext.ObjectType; else sqlType = EntityType; // 获取类上的所有自定义特性,包括继承的特性 var classAttributes = sqlType.GetCustomAttributes(true); // 如果你知道具体要查找的特性类型,可以直接获取它 var sugarTable = Attribute.GetCustomAttribute(sqlType, typeof(SugarTable)) as SugarTable; if (sugarTable == null) return new ValidationResult($"[{validationContext.MemberName}]无法识别SugarTable表信息!"); sqlTable = sugarTable.TableName; // 假设我们要检查 实体是否有 租户过滤特性 hasTenantFilter = sqlType.GetInterfaces().Any(it => it.Name == "ITenantIdFilter"); // 假设我们要检查 实体是否有 软删除过滤特性 hasDeletedFilter = sqlType.GetInterfaces().Any(it => it.Name == "IDeletedFilter"); //字段类型 sqlPropertyType = sqlType.GetProperty(sqlProperty)!.PropertyType; // 获取当前对象实例及其主键值 var propertyInfo = validationContext.ObjectType.GetProperty("Id"); var primaryKeyValue = propertyInfo?.GetValue(validationContext.ObjectInstance); long idVal = 0; if (primaryKeyValue == null) return new ValidationResult($"[{validationContext.MemberName}]无法识别主键信息!"); else idVal = primaryKeyValue.ToString()!.ToLong(); string sql = $"select count(id) from {sqlTable} where "; if (sqlPropertyType == typeof(string)) sql += $"{sqlProperty}='{value.ToString()}'"; else if (sqlPropertyType == typeof(int)) sql += $"{sqlProperty}={value}"; else if (sqlPropertyType == typeof(long)) sql += $"{sqlProperty}={value}"; else return new ValidationResult($"[{validationContext.MemberName}]不支持的字段类型,只支持【string,int,long】!"); if (idVal > 0) sql += $" and Id != {idVal}"; var userInfo = GlobalContext.UserInfo; if (hasTenantFilter) if (userInfo == null) return new ValidationResult($"[{validationContext.MemberName}]没有找到租户信息!"); else if(!userInfo.IsSuperAdmin) sql += $" and Tenantid={userInfo.TenantId}"; if (hasDeletedFilter) sql += $" and IsDelete=0"; var res = sqlClient.Ado.SqlQuerySingle(sql); if (res > 0) return new ValidationResult(!string.IsNullOrEmpty(ErrorMessage) ? ErrorMessage : $"该{validationContext.MemberName}已存在,请输入其他值。"); // 执行同步验证逻辑 return ValidationResult.Success!; } } }