sunpengfei
2025-08-05 1ddd1094f635bdc69e1e236353aa77d5b400f007
FlexJobApi.Core/Utils/DbUtils/DbUtils.cs
@@ -5,6 +5,7 @@
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;
@@ -18,38 +19,27 @@
    public static class DbUtils
    {
        /// <summary>
        /// 生成实体注释
        /// 生成实体
        /// </summary>
        /// <param name="modelBuilder"></param>
        /// <param name="dbContextLocator"></param>
        /// <returns></returns>
        public static async Task BuildEntityComment(ModelBuilder modelBuilder, Type dbContextLocator = null)
        public static async Task BuildEntity(ModelBuilder modelBuilder, Type dbContextLocator = null)
        {
            var xmlDoc = await XmlDocUtils.GetXmlDocAsync();
            var entityTypes = App.Assemblies
                .Where(it => it.FullName.Contains("FlexJob"))
                .SelectMany(it => it.GetTypes())
                .Where(it =>
                    it.IsClass
                    && !it.IsAbstract
                    && typeof(IPrivateEntity).IsAssignableFrom(it)
                    && (dbContextLocator == null
                    ? it.BaseType == typeof(CommonEntity)
                    : it.BaseType.GenericTypeArguments.Any(it => it == dbContextLocator)))
                .ToList();
            foreach (var entityType in entityTypes)
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                Console.WriteLine($"正在生成表:{entityType.Name}");
                // 获取实体类的XML注释,并设置为表注释
                var entityBuilder = modelBuilder.Entity(entityType);
                string typeComment = (await entityType.GetXmlDocMemberAsync(xmlDoc))?.Summary;
                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.GetProperties()
                var properties = entityType.ClrType.GetProperties()
                    .Where(p =>
                        p.CanRead
                        && p.CanWrite
@@ -64,7 +54,22 @@
                        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<int> result)
@@ -118,26 +123,33 @@
                    {
                        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?.ToDateTime() == null)
                    if (prop != null)
                    {
                        prop.CurrentValue = DateTimeOffset.Now;
                    }
                    // 赋值用户信息Id
                    prop = entity.Property(nameof(CommonEntity.UpdatedUserInfoId));
                    if (prop != null && prop.CurrentValue == null)
                    if (prop != null)
                    {
                        prop.CurrentValue = logier?.UserInfoId;
                    }
                    // 赋值跟踪Id
                    prop = entity.Property(nameof(CommonEntity.TraceId));
                    if (prop != null && prop.CurrentValue == null)
                    if (prop != null)
                    {
                        prop.CurrentValue = App.GetTraceId();
                    }
@@ -148,7 +160,7 @@
                        entity.State = EntityState.Modified;
                        prop = entity.Property(nameof(CommonEntity.IsDeleted));
                        if (prop != null && prop.CurrentValue == null)
                        if (prop != null)
                        {
                            prop.CurrentValue = true;
                        }
@@ -190,21 +202,6 @@
                .ToDictionary(p => p.Metadata.Name, p => getOldValues ? p.OriginalValue : p.CurrentValue);
            return JsonConvert.SerializeObject(properties);
        }
        public static void OnCreating(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator)
        {
            var metadata = entityBuilder.Metadata;
            var parameter = Expression.Parameter(metadata.ClrType, "e");
            var property = Expression.Property(parameter, nameof(CommonEntity.IsDeleted));
            var falseConstant = Expression.Constant(false, typeof(bool));
            var fakeDeleteQueryFilterExpression = Expression.Lambda(
                Expression.Equal(property, falseConstant),
                parameter
            );
            if (fakeDeleteQueryFilterExpression == null) return;
            entityBuilder.HasQueryFilter(fakeDeleteQueryFilterExpression);
        }
    }
}