using Furion; using Furion.DatabaseAccessor; using Furion.DistributedIDGenerator; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.Core { public static class DbUtils { /// /// 生成实体 /// /// /// /// public static async Task BuildEntity(ModelBuilder modelBuilder, Type dbContextLocator = null) { var xmlDoc = await XmlDocUtils.GetXmlDocAsync(); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { Console.WriteLine($"正在生成表:{entityType.Name}"); // 获取实体类的XML注释,并设置为表注释 var entityBuilder = modelBuilder.Entity(entityType.ClrType); string typeComment = (await entityType.ClrType.GetXmlDocMemberAsync(xmlDoc))?.Summary; if (!string.IsNullOrEmpty(typeComment)) { Console.WriteLine($"正在生成表注释:{entityType.Name}-{typeComment}"); entityBuilder.ToTable(it => it.HasComment(typeComment)); } // 获取实体属性的XML注释,并设置为列注释 var properties = entityType.ClrType.GetProperties() .Where(p => p.CanRead && p.CanWrite && !typeof(System.Collections.ICollection).IsAssignableFrom(p.PropertyType) && (p.PropertyType.IsClass ? p.PropertyType.FullName.Contains("System.") : true)); foreach (var property in properties) { string propComment = (await property.GetXmlDocMemberAsync(xmlDoc))?.Summary; if (!string.IsNullOrEmpty(propComment)) { Console.WriteLine($"正在生成属性注释:{property.Name}-{propComment}"); entityBuilder.Property(property.Name).HasComment(propComment); } } if (typeof(CommonEntity).IsAssignableFrom(entityType.ClrType)) { // 构建筛选条件:IsDeleted == false var parameter = Expression.Parameter(entityType.ClrType, "e"); var property = Expression.Property(parameter, "IsDeleted"); var constant = Expression.Constant(false); var equal = Expression.Equal(property, constant); var lambda = Expression.Lambda(equal, parameter); // 添加全局筛选器 modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda); } } Console.WriteLine("数据库链接地址:" + App.Configuration.GetConnectionString("FlexJobApi")); } public static void SavingChangesEvent(DbContextEventData eventData, InterceptionResult result) { // 获取当前事件对应上下文 var dbContext = eventData.Context; // 强制重新检查一边实体更改信息 // dbContext.ChangeTracker.DetectChanges(); // 获取所有更改,删除,新增的实体 var dbAuditLogIgnoreType = typeof(IDbAuditLogIgnore); var physicalDeletionType = typeof(IPhysicalDeletion); var entities = dbContext.ChangeTracker.Entries() .Where(u => u.GetType() != typeof(DbAuditLog) && (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)) .ToList(); // 通过请求中获取当前操作人 var logier = JwtUtils.GetCurrentLogier(); // 获取所有已更改的实体 foreach (var entity in entities) { // 获取实体类型 var entityType = entity.Entity.GetType(); if (entity.State == EntityState.Added) { // 赋值创建日期 var prop = entity.Property(nameof(CommonEntity.CreatedTime)); if (prop != null && prop.CurrentValue?.ToDateTime() == null) { prop.CurrentValue = DateTimeOffset.Now; } // 生成Id prop = entity.Property(nameof(CommonEntity.Id)); var defaultValue = Activator.CreateInstance(prop.Metadata.ClrType); if (prop != null && (prop.CurrentValue == null || prop.CurrentValue.Equals(defaultValue))) { prop.CurrentValue = IDGen.NextID(); } // 赋值用户信息Id prop = entity.Property(nameof(CommonEntity.CreatedUserInfoId)); if (prop != null && prop.CurrentValue == null) { prop.CurrentValue = logier?.UserInfoId; } // 赋值跟踪Id prop = entity.Property(nameof(CommonEntity.TraceId)); if (prop != null) { prop.CurrentValue = App.GetTraceId(); } } else { // 赋值修改日期 var prop = entity.Property(nameof(CommonEntity.UpdatedTime)); if (prop != null) { prop.CurrentValue = DateTimeOffset.Now; } // 赋值用户信息Id prop = entity.Property(nameof(CommonEntity.UpdatedUserInfoId)); if (prop != null) { prop.CurrentValue = logier?.UserInfoId; } // 赋值跟踪Id prop = entity.Property(nameof(CommonEntity.TraceId)); if (prop != null) { prop.CurrentValue = App.GetTraceId(); } // 软删除 if (entity.State == EntityState.Deleted && !physicalDeletionType.IsAssignableFrom(entityType)) { entity.State = EntityState.Modified; prop = entity.Property(nameof(CommonEntity.IsDeleted)); if (prop != null) { prop.CurrentValue = true; } } } if (dbAuditLogIgnoreType.IsAssignableFrom(entityType)) { continue; } Db.GetRepository().InsertNow(new DbAuditLog { Id = IDGen.NextID(), TableName = entityType.Name, PrimaryKey = (Guid)entity.Property("Id").CurrentValue, NewValues = entity.State == EntityState.Added || entity.State == EntityState.Modified ? GetPropertyValuesAsJson(entity) : null, OldValues = entity.State == EntityState.Deleted || entity.State == EntityState.Modified ? GetPropertyValuesAsJson(entity, entity.State == EntityState.Modified) : null, Operate = entity.State == EntityState.Added ? EnumDbAuditOperate.Added : entity.State == EntityState.Modified ? EnumDbAuditOperate.Modified : EnumDbAuditOperate.Deleted, TraceId = App.GetTraceId(), CreatedTime = DateTime.Now, CreatedUserInfoId = logier?.UserInfoId, }); } } private static string GetPropertyValuesAsJson(EntityEntry entry, bool getOldValues = false) { var properties = entry.Properties .Where(p => getOldValues ? p.IsModified : true) .ToDictionary(p => p.Metadata.Name, p => getOldValues ? p.OriginalValue : p.CurrentValue); return JsonConvert.SerializeObject(properties); } } }