ABP EfCore
ABP EfCore
2023/6/1
➡️

ef core

[DependsOn(typeof(AbpDddDomainModule))]
public class AbpEntityFrameworkCoreModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpDbContextOptions>(options =>
        {
            options.PreConfigure(abpDbContextConfigurationContext =>
            {
                abpDbContextConfigurationContext.DbContextOptions
                    .ConfigureWarnings(warnings =>
                    {
                        warnings.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning);
                    });
            });
        });

        context.Services.TryAddTransient(typeof(IDbContextProvider<>),
        typeof(UnitOfWorkDbContextProvider<>));
        context.Services.AddTransient(typeof(IDbContextEventOutbox<>),
        typeof(DbContextEventOutbox<>));
        context.Services.AddTransient(typeof(IDbContextEventInbox<>),
        typeof(DbContextEventInbox<>));
    }
}

AbpEntityFrameworkCoreModule 用到了 扩展属性

扩展类配置选项

public class ObjectExtensionPropertyInfoEfCoreMappingOptions
{
    [NotNull]
    public ObjectExtensionPropertyInfo ExtensionProperty { get; }

    [NotNull]
    public ObjectExtensionInfo ObjectExtension => ExtensionProperty.ObjectExtension;

    // EntityTypeBuilder  PropertyBuilder   在 OnModelCreating 用到的俩个配置类
    public Action<EntityTypeBuilder, PropertyBuilder>? EntityTypeAndPropertyBuildAction
     { get; set; }

    public ObjectExtensionPropertyInfoEfCoreMappingOptions(
        [NotNull] ObjectExtensionPropertyInfo extensionProperty)
    {
        ExtensionProperty = Check.NotNull(extensionProperty, nameof(extensionProperty));
    }

    public ObjectExtensionPropertyInfoEfCoreMappingOptions(
        [NotNull] ObjectExtensionPropertyInfo extensionProperty,
        Action<EntityTypeBuilder, PropertyBuilder>? entityTypeAndPropertyBuildAction)
    {
        ExtensionProperty = Check.NotNull(extensionProperty, nameof(extensionProperty));

        EntityTypeAndPropertyBuildAction = entityTypeAndPropertyBuildAction;
    }
}

扩展属性配置选项

public class ObjectExtensionPropertyInfoEfCoreMappingOptions
{
    [NotNull]
    public ObjectExtensionPropertyInfo ExtensionProperty { get; }

    [NotNull]
    public ObjectExtensionInfo ObjectExtension => ExtensionProperty.ObjectExtension;


    public Action<EntityTypeBuilder, PropertyBuilder>?
    EntityTypeAndPropertyBuildAction { get; set; }


    public ObjectExtensionPropertyInfoEfCoreMappingOptions(
        [NotNull] ObjectExtensionPropertyInfo extensionProperty)
    {
        ExtensionProperty = Check.NotNull(extensionProperty, nameof(extensionProperty));
    }

    public ObjectExtensionPropertyInfoEfCoreMappingOptions(
        [NotNull] ObjectExtensionPropertyInfo extensionProperty,
        Action<EntityTypeBuilder, PropertyBuilder>? entityTypeAndPropertyBuildAction)
    {
        ExtensionProperty = Check.NotNull(extensionProperty, nameof(extensionProperty));

        EntityTypeAndPropertyBuildAction = entityTypeAndPropertyBuildAction;
    }
}

扩展对象

public static class EfCoreObjectExtensionInfoExtensions
{
    public const string EfCoreDbContextConfigurationName = "EfCoreDbContextMapping";
    public const string EfCoreEntityConfigurationName = "EfCoreEntityMapping";

     // 给扩展对象增加扩展属性
    public static ObjectExtensionInfo MapEfCoreProperty<TProperty>(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo,
        [NotNull] string propertyName,
        [CanBeNull] Action<EntityTypeBuilder, PropertyBuilder>
         entityTypeAndPropertyBuildAction)
    {
        return objectExtensionInfo.MapEfCoreProperty(
            typeof(TProperty),
            propertyName,
            entityTypeAndPropertyBuildAction
        );
    }

     // 给扩展对象增加扩展属性
    public static ObjectExtensionInfo MapEfCoreProperty(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo,
        [NotNull] Type propertyType,
        [NotNull] string propertyName,
        [CanBeNull] Action<EntityTypeBuilder, PropertyBuilder>
        entityTypeAndPropertyBuildAction)
    {
        Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));

        return objectExtensionInfo.AddOrUpdateProperty(
            propertyType,
            propertyName,
            //objectExtensionInfo 里的  ObjectExtensionPropertyInfo 进行配置
            options =>
            {
                //扩展方法  key: EfCoreMapping value:
                // ObjectExtensionPropertyInfoEfCoreMappingOptions
                //加入  ObjectExtensionPropertyInfo 的 config 配置字典
                options.MapEfCore(
                    entityTypeAndPropertyBuildAction
                );
            }
        );
    }

    // 给  ObjectExtensionInfo  增加  EntityTypeBuilder 配置
    public static ObjectExtensionInfo MapEfCoreEntity(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo,
        [NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
    {
        Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));

        var mappingOptionList = new List<ObjectExtensionInfoEfCoreMappingOptions>
            {
                new ObjectExtensionInfoEfCoreMappingOptions(
                    objectExtensionInfo,
                    entityTypeBuildAction)
            };

        // EfCoreEntityMapping
        objectExtensionInfo.Configuration.AddOrUpdate(EfCoreEntityConfigurationName,
        mappingOptionList,
            (k, v) =>
            {
                v.As<List<ObjectExtensionInfoEfCoreMappingOptions>>().
                Add(mappingOptionList.First());
                return v;
            });

        return objectExtensionInfo;
    }

    // 给  ObjectExtensionInfo  增加  ModelBuilder 配置
    public static ObjectExtensionInfo MapEfCoreDbContext(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo,
        [NotNull] Action<ModelBuilder> modelBuildAction)
    {
        Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));

        var mappingOptionList = new List<ObjectExtensionInfoEfCoreMappingOptions>
            {
                new ObjectExtensionInfoEfCoreMappingOptions(
                    objectExtensionInfo,
                    modelBuildAction)
            };

        objectExtensionInfo.Configuration.AddOrUpdate(
          EfCoreDbContextConfigurationName, mappingOptionList,
            (k, v) =>
            {
                v.As<List<ObjectExtensionInfoEfCoreMappingOptions>>()
                .Add(mappingOptionList.First());
                return v;
            });

        return objectExtensionInfo;
    }

    //获取上面的配置
    public static List<ObjectExtensionInfoEfCoreMappingOptions> GetEfCoreEntityMappings(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo)
    {
        Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));

        return !objectExtensionInfo.Configuration.TryGetValue(
          EfCoreEntityConfigurationName, out var options) ?
            new List<ObjectExtensionInfoEfCoreMappingOptions>() :
             options.As<List<ObjectExtensionInfoEfCoreMappingOptions>>();
    }

    public static List<ObjectExtensionInfoEfCoreMappingOptions>
    GetEfCoreDbContextMappings(
        [NotNull] this ObjectExtensionInfo objectExtensionInfo)
    {
        Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));

        return !objectExtensionInfo.Configuration.TryGetValue(
          EfCoreDbContextConfigurationName, out var options) ?
            new List<ObjectExtensionInfoEfCoreMappingOptions>() :
             options.As<List<ObjectExtensionInfoEfCoreMappingOptions>>();
    }
}

扩展属性增加配置

public static class EfCoreObjectExtensionPropertyInfoExtensions
{
    public const string EfCorePropertyConfigurationName = "EfCoreMapping";

    [NotNull]
    public static ObjectExtensionPropertyInfo MapEfCore(
        [NotNull] this ObjectExtensionPropertyInfo propertyExtension)
    {
        Check.NotNull(propertyExtension, nameof(propertyExtension));

        propertyExtension.Configuration[EfCorePropertyConfigurationName] =
            new ObjectExtensionPropertyInfoEfCoreMappingOptions(
                propertyExtension
            );

        return propertyExtension;
    }


    [NotNull]
    public static ObjectExtensionPropertyInfo MapEfCore(
        [NotNull] this ObjectExtensionPropertyInfo propertyExtension,
        Action<EntityTypeBuilder, PropertyBuilder>? entityTypeAndPropertyBuildAction)
    {
        Check.NotNull(propertyExtension, nameof(propertyExtension));

        propertyExtension.Configuration[EfCorePropertyConfigurationName] =
            new ObjectExtensionPropertyInfoEfCoreMappingOptions(
                propertyExtension,
                entityTypeAndPropertyBuildAction
            );

        return propertyExtension;
    }

    public static ObjectExtensionPropertyInfoEfCoreMappingOptions? GetEfCoreMappingOrNull(
        [NotNull] this ObjectExtensionPropertyInfo propertyExtension)
    {
        Check.NotNull(propertyExtension, nameof(propertyExtension));

        return propertyExtension
                .Configuration
                .GetOrDefault(EfCorePropertyConfigurationName)
            as ObjectExtensionPropertyInfoEfCoreMappingOptions;
    }

    public static bool IsMappedToFieldForEfCore(
        [NotNull] this ObjectExtensionPropertyInfo propertyExtension)
    {
        Check.NotNull(propertyExtension, nameof(propertyExtension));

        return propertyExtension
            .Configuration
            .ContainsKey(EfCorePropertyConfigurationName);
    }
}

扩展上下文

public static class EfCoreObjectExtensionManagerExtensions
{
    //建立 TDbContext , ObjectExtensionInfo 绑定关系 在 objectExtensionManager 字典
    public static ObjectExtensionManager MapEfCoreDbContext<TDbContext>(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] Action<ModelBuilder> modelBuilderAction)
        where TDbContext : DbContext
    {

        return objectExtensionManager.AddOrUpdate(
            typeof(TDbContext),
            options =>
            {
                options.MapEfCoreDbContext(modelBuilderAction);
            });
    }

    //建立 entityType , ObjectExtensionInfo 绑定关系 在 objectExtensionManager 字典
    public static ObjectExtensionManager MapEfCoreEntity<TEntity>(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
        where TEntity : IEntity
    {
        return MapEfCoreEntity(
            objectExtensionManager,
            typeof(TEntity),
            entityTypeBuildAction);
    }

    //建立 entityType , ObjectExtensionInfo 绑定关系 在 objectExtensionManager 字典
    public static ObjectExtensionManager MapEfCoreEntity(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] Type entityType,
        [NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
    {
        Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));

        //建立 entityType , ObjectExtensionInfo 绑定关系 在 objectExtensionManager 字典
        return objectExtensionManager.AddOrUpdate(
            entityType,
            options =>
            {
                options.MapEfCoreEntity(entityTypeBuildAction);
            });
    }

    public static ObjectExtensionManager MapEfCoreProperty<TEntity, TProperty>(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] string propertyName)
        where TEntity : IHasExtraProperties, IEntity
    {
        //
        return objectExtensionManager.MapEfCoreProperty(
            typeof(TEntity),
            typeof(TProperty),
            propertyName
        );
    }

     // 给 扩展  entityType ,增加 扩展属性
    public static ObjectExtensionManager MapEfCoreProperty(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] Type entityType,
        [NotNull] Type propertyType,
        [NotNull] string propertyName)
    {
        Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));

        return objectExtensionManager.AddOrUpdateProperty(
            entityType,
            propertyType,
            propertyName,
            options => { options.MapEfCore(); }
        );
    }

    // 给 扩展  entityType ,增加 扩展属性
    public static ObjectExtensionManager MapEfCoreProperty<TEntity, TProperty>(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] string propertyName,
        [CanBeNull] Action<EntityTypeBuilder, PropertyBuilder>
        entityTypeAndPropertyBuildAction)
        where TEntity : IHasExtraProperties, IEntity
    {
        return objectExtensionManager.MapEfCoreProperty(
            typeof(TEntity),
            typeof(TProperty),
            propertyName,
            entityTypeAndPropertyBuildAction
        );
    }

    //给 扩展  entityType ,增加 扩展属性
    public static ObjectExtensionManager MapEfCoreProperty(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] Type entityType,
        [NotNull] Type propertyType,
        [NotNull] string propertyName,
        [CanBeNull] Action<EntityTypeBuilder, PropertyBuilder>
        entityTypeAndPropertyBuildAction)
    {
        Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));


        return objectExtensionManager.AddOrUpdateProperty(
            entityType,
            propertyType,
            propertyName,
            options =>
            {
                options.MapEfCore(
                    entityTypeAndPropertyBuildAction
                );
            }
        );
    }

    //执行 实体的 objectExtension  ,ObjectExtensionPropertyInfo 上的配置
    public static void ConfigureEfCoreEntity(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] EntityTypeBuilder typeBuilder)
    {
        Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
        Check.NotNull(typeBuilder, nameof(typeBuilder));

        var objectExtension = objectExtensionManager.GetOrNull(
          typeBuilder.Metadata.ClrType);
        if (objectExtension == null)
        {
            return;
        }

        var efCoreEntityMappings = objectExtension.GetEfCoreEntityMappings();

        foreach (var efCoreEntityMapping in efCoreEntityMappings)
        {
            efCoreEntityMapping.EntityTypeBuildAction?.Invoke(typeBuilder);
        }

        foreach (var property in objectExtension.GetProperties())
        {
            var efCoreMapping = property.GetEfCoreMappingOrNull();
            if (efCoreMapping == null)
            {
                continue;
            }

            /* Prevent multiple calls to the entityTypeBuilder.Property(...) method */
            if (typeBuilder.Metadata.FindProperty(property.Name) != null)
            {
                continue;
            }

            var propertyBuilder = typeBuilder.Property(property.Type, property.Name);

            efCoreMapping.EntityTypeAndPropertyBuildAction?.Invoke(
              typeBuilder, propertyBuilder);

            efCoreMapping.PropertyBuildAction?.Invoke(propertyBuilder);

        }
    }

    //执行  TDbContext   objectExtension  上的配置
    public static void ConfigureEfCoreDbContext<TDbContext>(
        [NotNull] this ObjectExtensionManager objectExtensionManager,
        [NotNull] ModelBuilder modelBuilder)
        where TDbContext : DbContext
    {
        Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
        Check.NotNull(modelBuilder, nameof(modelBuilder));

        var objectExtension = objectExtensionManager.GetOrNull(typeof(TDbContext));
        if (objectExtension == null)
        {
            return;
        }

        var efCoreDbContextMappings = objectExtension.GetEfCoreDbContextMappings();

        foreach (var efCoreDbContextMapping in efCoreDbContextMappings)
        {
            efCoreDbContextMapping.ModelBuildAction?.Invoke(modelBuilder);
        }
    }
}

EF 提供的 DbContext

EF 的 DbContext 非常复杂的一个上下文类,限制条件一个上下文不能在多个线程里并发的执行因为 DbContext 不支持多线程并发

  1. IInfrastructure:IInfrastructure 是 EF Core 中的内部接口,它允许 DbContext 访问底层的 IServiceProvider。
  2. IDbContextDependencies:这个接口通常包含了 DbContext 的依赖项,用于内部操作和配置。
  3. IDbSetCache:这个接口可能用于缓存 DbSet 对象,以提高性能。 4 .IDbContextPoolable:这个 接口可能用于支持 DbContext 的池化,以减少资源消耗。

微软的的定义 A DbContext instance represents a session with the database and can be used to query and save instances of your entities. DbContext is a combination of the Unit Of Work and Repository patterns.

public class DbContext :
    IInfrastructure<IServiceProvider>,
    IDbContextDependencies,
    IDbSetCache,
    IDbContextPoolable
    {

    }
public interface IDbContextDependencies
{
    IDbSetSource SetSource { get; }
    IEntityFinderFactory EntityFinderFactory { get; }
    IAsyncQueryProvider QueryProvider { get; }
    IStateManager StateManager { get; }
    IChangeDetector ChangeDetector { get; }
    IEntityGraphAttacher EntityGraphAttacher { get; }
    IExceptionDetector ExceptionDetector { get; }
    IDiagnosticsLogger<DbLoggerCategory.Update> UpdateLogger { get; }
    IDiagnosticsLogger<DbLoggerCategory.Infrastructure> InfrastructureLogger { get; }
}
public interface IDbSetCache
{
    object GetOrAddSet(IDbSetSource source,
    [DynamicallyAccessedMembers(IEntityType.DynamicallyAccessedMemberTypes)] Type type);
    object GetOrAddSet(
        IDbSetSource source,
        string entityTypeName,
        [DynamicallyAccessedMembers(IEntityType.DynamicallyAccessedMemberTypes)] Type type);
    IEnumerable<object> GetSets();
}

IEfCoreDbContext abp 定义的上下文接口

IEfCoreDbContext 一样继承 DbContext 的所有接口

public interface IEfCoreDbContext : IDisposable, IInfrastructure<IServiceProvider>,
 IDbContextDependencies, IDbSetCache, IDbContextPoolable
{
    EntityEntry<TEntity> Attach<TEntity>([NotNull] TEntity entity) where TEntity : class;

    EntityEntry Attach([NotNull] object entity);

    int SaveChanges();

    int SaveChanges(bool acceptAllChangesOnSuccess);

    Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken
    cancellationToken = default);

    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// This method will call the DbContext <see cref="SaveChangesAsync(bool,
    ///CancellationToken)"/> method directly of EF Core, which doesn't apply concepts of abp.
    /// </summary>
    Task<int> SaveChangesOnDbContextAsync(bool acceptAllChangesOnSuccess,
    CancellationToken cancellationToken = default);

    DbSet<T> Set<T>()
        where T : class;

    DatabaseFacade Database { get; }

    ChangeTracker ChangeTracker { get; }

    EntityEntry Add([NotNull] object entity);

    EntityEntry<TEntity> Add<TEntity>([NotNull] TEntity entity) where TEntity : class;

    ValueTask<EntityEntry> AddAsync([NotNull] object entity, CancellationToken
    cancellationToken = default);

    ValueTask<EntityEntry<TEntity>> AddAsync<TEntity>([NotNull] TEntity entity,
    CancellationToken cancellationToken = default) where TEntity : class;

    void AddRange([NotNull] IEnumerable<object> entities);

    void AddRange([NotNull] params object[] entities);

    Task AddRangeAsync([NotNull] params object[] entities);

    Task AddRangeAsync([NotNull] IEnumerable<object> entities,
     CancellationToken cancellationToken = default);

    void AttachRange([NotNull] IEnumerable<object> entities);

    void AttachRange([NotNull] params object[] entities);

    EntityEntry<TEntity> Entry<TEntity>([NotNull] TEntity entity) where TEntity : class;

    EntityEntry Entry([NotNull] object entity);

    object? Find([NotNull] Type entityType, [NotNull] params object[] keyValues);

    TEntity? Find<TEntity>([NotNull] params object[] keyValues) where TEntity : class;

    ValueTask<object?> FindAsync([NotNull] Type entityType, [NotNull] object[] keyValues,
    CancellationToken cancellationToken);

    ValueTask<TEntity?> FindAsync<TEntity>([NotNull] object[] keyValues,
    CancellationToken cancellationToken) where TEntity : class;

    ValueTask<TEntity?> FindAsync<TEntity>([NotNull] params object[] keyValues)
     where TEntity : class;

    ValueTask<object?> FindAsync([NotNull] Type entityType, [NotNull]
     params object[] keyValues);

    EntityEntry<TEntity> Remove<TEntity>([NotNull] TEntity entity) where TEntity : class;

    EntityEntry Remove([NotNull] object entity);

    void RemoveRange([NotNull] IEnumerable<object> entities);

    void RemoveRange([NotNull] params object[] entities);

    EntityEntry<TEntity> Update<TEntity>([NotNull] TEntity entity) where TEntity : class;

    EntityEntry Update([NotNull] object entity);

    void UpdateRange([NotNull] params object[] entities);

    void UpdateRange([NotNull] IEnumerable<object> entities);
}
public class AbpEfCoreDbContextInitializationContext
{
    public IUnitOfWork UnitOfWork { get; }

    public AbpEfCoreDbContextInitializationContext(IUnitOfWork unitOfWork)
    {
        UnitOfWork = unitOfWork;
    }
}

//增加了初始化
public interface IAbpEfCoreDbContext : IEfCoreDbContext
{
    //初始化获取到了工作单元
    void Initialize(AbpEfCoreDbContextInitializationContext initializationContext);
}

AbpDbContext where TDbContext : DbContext

AbpDbContext ABP 定义自己的上下文,上下文干活要靠 DbContext,但是原来的 DbContext,自带的 工作单元和仓储模式要失效,要不然不能融入 ABP 里

public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency
    where TDbContext : DbContext
{
    public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;

    protected virtual Guid? CurrentTenantId => CurrentTenant?.Id;

    protected virtual bool IsMultiTenantFilterEnabled =>
    DataFilter?.IsEnabled<IMultiTenant>() ?? false;

    protected virtual bool IsSoftDeleteFilterEnabled =>
    DataFilter?.IsEnabled<ISoftDelete>() ?? false;

    public ICurrentTenant CurrentTenant =>
    LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();

    public IGuidGenerator GuidGenerator =>
    LazyServiceProvider.LazyGetService<IGuidGenerator>(SimpleGuidGenerator.Instance);

    public IDataFilter DataFilter =>
    LazyServiceProvider.LazyGetRequiredService<IDataFilter>();

    public IEntityChangeEventHelper EntityChangeEventHelper =>
     LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(
      NullEntityChangeEventHelper.Instance);

    public IAuditPropertySetter AuditPropertySetter =>
    LazyServiceProvider.LazyGetRequiredService<IAuditPropertySetter>();

    public IEntityHistoryHelper EntityHistoryHelper =>
     LazyServiceProvider.LazyGetService<IEntityHistoryHelper>(
      NullEntityHistoryHelper.Instance);

    public IAuditingManager AuditingManager =>
    LazyServiceProvider.LazyGetRequiredService<IAuditingManager>();

    public IUnitOfWorkManager UnitOfWorkManager =>
    LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();

    public IClock Clock => LazyServiceProvider.LazyGetRequiredService<IClock>();

    public IDistributedEventBus DistributedEventBus =>
     LazyServiceProvider.LazyGetRequiredService<IDistributedEventBus>();

    public ILocalEventBus LocalEventBus =>
     LazyServiceProvider.LazyGetRequiredService<ILocalEventBus>();

    public ILogger<AbpDbContext<TDbContext>> Logger =>
    LazyServiceProvider.LazyGetService<ILogger<AbpDbContext<TDbContext>>>(
      NullLogger<AbpDbContext<TDbContext>>.Instance);

    // 为了通过反射调用 这里写成静态方法,因为 db context 里配置的是 Model 里的所有 entity

    private static readonly MethodInfo ConfigureBasePropertiesMethodInfo
        = typeof(AbpDbContext<TDbContext>)
            .GetMethod(
                nameof(ConfigureBaseProperties),
                BindingFlags.Instance | BindingFlags.NonPublic
            )!;

    private static readonly MethodInfo ConfigureValueConverterMethodInfo
        = typeof(AbpDbContext<TDbContext>)
            .GetMethod(
                nameof(ConfigureValueConverter),
                BindingFlags.Instance | BindingFlags.NonPublic
            )!;

    private static readonly MethodInfo ConfigureValueGeneratedMethodInfo
        = typeof(AbpDbContext<TDbContext>)
            .GetMethod(
                nameof(ConfigureValueGenerated),
                BindingFlags.Instance | BindingFlags.NonPublic
            )!;

    protected AbpDbContext(DbContextOptions<TDbContext> options)
        : base(options)
    {
    }

    // 通过反射的方式进行 entity model 的配置,这里的配置是对所有的模型进行配置
    // 这个方法一定会调用,因为是全局的 Entity 配置
    // 重写 DBContext 上下文的 IEfCoreDbContext
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // ef core 模型配置默认什么也没做
        base.OnModelCreating(modelBuilder);

        //给 Model 设置元素据 数据提供者字符串名
        TrySetDatabaseProvider(modelBuilder);

        foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        {
            // 约定的配置属性 审计里的属性, 并发标记
            ConfigureBasePropertiesMethodInfo
                .MakeGenericMethod(entityType.ClrType)
                .Invoke(this, new object[] { modelBuilder, entityType });
            // 注册默认的值转换器  AbpDateTimeValueConverter
            // abp 没有使用 datetimeOff,故使用了  datetime  值转换器
            ConfigureValueConverterMethodInfo
                .MakeGenericMethod(entityType.ClrType)
                .Invoke(this, new object[] { modelBuilder, entityType });
            // 配置默认的值生成器
            ConfigureValueGeneratedMethodInfo
                .MakeGenericMethod(entityType.ClrType)
                .Invoke(this, new object[] { modelBuilder, entityType });
        }
    }

    // 设置数据库提供者
    // EfCoreDatabaseProvider 是个枚举类
    protected virtual void TrySetDatabaseProvider(ModelBuilder modelBuilder)
    {
        // 通过 ef  获取到当前的数据库提供程序,并转换为 abp 的枚举字符串
        var provider = GetDatabaseProviderOrNull(modelBuilder);
        if (provider != null)
        {
            //给模型统一的设置这个枚举字符串
            modelBuilder.SetDatabaseProvider(provider.Value);
        }
    }

    protected virtual EfCoreDatabaseProvider? GetDatabaseProviderOrNull(
      ModelBuilder modelBuilder)
    {
        switch (Database.ProviderName)
        {
            case "Microsoft.EntityFrameworkCore.SqlServer":
                return EfCoreDatabaseProvider.SqlServer;
            case "Npgsql.EntityFrameworkCore.PostgreSQL":
                return EfCoreDatabaseProvider.PostgreSql;
            case "Pomelo.EntityFrameworkCore.MySql":
                return EfCoreDatabaseProvider.MySql;
            case "Oracle.EntityFrameworkCore":
            case "Devart.Data.Oracle.Entity.EFCore":
                return EfCoreDatabaseProvider.Oracle;
            case "Microsoft.EntityFrameworkCore.Sqlite":
                return EfCoreDatabaseProvider.Sqlite;
            case "Microsoft.EntityFrameworkCore.InMemory":
                return EfCoreDatabaseProvider.InMemory;
            case "FirebirdSql.EntityFrameworkCore.Firebird":
                return EfCoreDatabaseProvider.Firebird;
            case "Microsoft.EntityFrameworkCore.Cosmos":
                return EfCoreDatabaseProvider.Cosmos;
            default:
                return null;
        }
    }

    // 最核心的  SaveChanges ,重写了 父方法
    public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
    CancellationToken cancellationToken = default)
    {
      try
      {
          var auditLog = AuditingManager?.Current?.Log;
          List<EntityChangeInfo>? entityChangeList = null;
          if (auditLog != null)
          {
              entityChangeList = EntityHistoryHelper.CreateChangeList(
                ChangeTracker.Entries().ToList());
          }

          // 保存扩展属性到数据库 , 如果是修改或删除状态,就更新并发标记
          HandlePropertiesBeforeSave();

          // 生成领域事件
          var eventReport = CreateEventReport();
          //调用 db  context 的 SaveChangesAsync
          var result = await base.SaveChangesAsync(
            acceptAllChangesOnSuccess, cancellationToken);

          //把领域事件赋值给工作单元后,领域事件清空
          PublishEntityEvents(eventReport);

          if (entityChangeList != null)
          {
              EntityHistoryHelper.UpdateChangeList(entityChangeList);
              auditLog!.EntityChanges.AddRange(entityChangeList);
              Logger.LogDebug($"Added {entityChangeList.Count}
                entity changes to the current audit log");
          }

          return result;
      }
      catch (DbUpdateConcurrencyException ex)
      {
        if (ex.Entries.Count > 0)
        {
          var sb = new StringBuilder();
          sb.AppendLine(ex.Entries.Count > 1
              ? "There are some entries which are not saved due to concurrency exception:"
              : "There is an entry which is not saved due to concurrency exception:");
          foreach (var entry in ex.Entries)
          {
              sb.AppendLine(entry.ToString());
          }

          Logger.LogWarning(sb.ToString());
        }

        throw new AbpDbConcurrencyException(ex.Message, ex);
      }
      finally
      {
          ChangeTracker.AutoDetectChangesEnabled = true;
      }
    }

    // 发布事件
    private void PublishEntityEvents(EntityEventReport changeReport)
    {
        //把领域事件赋值给当前的工作单元了
        foreach (var localEvent in changeReport.DomainEvents)
        {

            UnitOfWorkManager.Current?.AddOrReplaceLocalEvent(
                new UnitOfWorkEventRecord(localEvent.EventData.GetType(),
                localEvent.EventData, localEvent.EventOrder)
            );
        }

        //把分布式事件赋值给当前的工作单元了
        foreach (var distributedEvent in changeReport.DistributedEvents)
        {
            UnitOfWorkManager.Current?.AddOrReplaceDistributedEvent(
                new UnitOfWorkEventRecord(distributedEvent.EventData.GetType(),
                distributedEvent.EventData, distributedEvent.EventOrder)
            );
        }
    }

    //直接执行  db  context 的保存,跳过 abp
    public virtual Task<int> SaveChangesOnDbContextAsync(bool acceptAllChangesOnSuccess,
    CancellationToken cancellationToken = default)
    {
        return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }

    //
    public virtual void Initialize(AbpEfCoreDbContextInitializationContext
     initializationContext)
    {
        if (initializationContext.UnitOfWork.Options.Timeout.HasValue &&
            Database.IsRelational() &&
            !Database.GetCommandTimeout().HasValue)
        {
            //把工作单元的超时时间给数据库
            Database.SetCommandTimeout(TimeSpan.FromMilliseconds(
              initializationContext.UnitOfWork.Options.Timeout.Value));
        }

        //级联删除的时机设置
        ChangeTracker.CascadeDeleteTiming = CascadeTiming.OnSaveChanges;

        //实体开始追踪或状态改变的事件发送给工作单元保存

        //实体开始被追踪发生的事件
        //数据库对象扩展属性的值给到扩展对象的扩展属性
        ChangeTracker.Tracked += ChangeTracker_Tracked;
        //实体状态变化发生的事件
        ChangeTracker.StateChanged += ChangeTracker_StateChanged;

        // UnitOfWorkManager ,不使用事务,工作单元内
        if (UnitOfWorkManager is AlwaysDisableTransactionsUnitOfWorkManager)
        {
            // SaveChanges()  不要自动开启事务
            Database.AutoTransactionBehavior = AutoTransactionBehavior.Never;
        }
    }

    //发送给工作单元
    protected virtual void ChangeTracker_Tracked(object? sender,
    EntityTrackedEventArgs e)
    {
        FillExtraPropertiesForTrackedEntities(e);
        PublishEventsForTrackedEntity(e.Entry);
    }

    //发送给工作单元
    protected virtual void ChangeTracker_StateChanged(object? sender,
    EntityStateChangedEventArgs e)
    {
        PublishEventsForTrackedEntity(e.Entry);
    }

    //那数据库属性的值,赋值给扩展对象的扩展属性
    protected virtual void FillExtraPropertiesForTrackedEntities(
      EntityTrackedEventArgs e)
    {
        var entityType = e.Entry.Metadata.ClrType;
        if (entityType == null)
        {
            return;
        }

        if (!(e.Entry.Entity is IHasExtraProperties entity))
        {
            return;
        }

        if (!e.FromQuery)
        {
            return;
        }

        var objectExtension = ObjectExtensionManager.Instance.GetOrNull(entityType);
        if (objectExtension == null)
        {
            return;
        }

        foreach (var property in objectExtension.GetProperties())
        {
            if (!property.IsMappedToFieldForEfCore())
            {
                continue;
            }

            /* Checking "currentValue != null" has a good advantage:
             * Assume that you we already using a named extra property,
             * then decided to create a field (entity extension) for it.
             * In this way, it prevents to delete old value in the JSON and
             * updates the field on the next save!
             */

            var currentValue = e.Entry.CurrentValues[property.Name];
            if (currentValue != null)
            {
                entity.ExtraProperties[property.Name] = currentValue;
            }
        }
    }

    //实体状态改变的事件发送给工作单元保存
    private void PublishEventsForTrackedEntity(EntityEntry entry)
    {
        switch (entry.State)
        {
            case EntityState.Added:
                ApplyAbpConceptsForAddedEntity(entry);
                EntityChangeEventHelper.PublishEntityCreatedEvent(entry.Entity);
                break;
            case EntityState.Modified:
                ApplyAbpConceptsForModifiedEntity(entry);
                if (entry.Properties.Any(x => x.IsModified &&
                 x.Metadata.ValueGenerated == ValueGenerated.Never))
                {
                    if (entry.Entity is ISoftDelete &&
                     entry.Entity.As<ISoftDelete>().IsDeleted)
                    {
                        EntityChangeEventHelper.PublishEntityDeletedEvent(entry.Entity);
                    }
                    else
                    {
                        EntityChangeEventHelper.PublishEntityUpdatedEvent(entry.Entity);
                    }
                }

                break;
            case EntityState.Deleted:
                ApplyAbpConceptsForDeletedEntity(entry);
                EntityChangeEventHelper.PublishEntityDeletedEvent(entry.Entity);
                break;
        }
    }

    // 在保存到数据库的时候,把扩展属性的值保存到数据库 ,如果是修改或删除状态,就更新并发标记
    protected virtual void HandlePropertiesBeforeSave()
    {
        foreach (var entry in ChangeTracker.Entries().ToList())
        {
            //在保存到数据库的时候,把扩展属性的值保存到数据库
            HandleExtraPropertiesOnSave(entry);
            // 如果是修改或删除状态,就更新并发标记
            if (entry.State.IsIn(EntityState.Modified, EntityState.Deleted))
            {
                UpdateConcurrencyStamp(entry);
            }
        }
    }

    //生成领域事件
    protected virtual EntityEventReport CreateEventReport()
    {
        // 领域事件
        var eventReport = new EntityEventReport();

        foreach (var entry in ChangeTracker.Entries().ToList())
        {
            var generatesDomainEventsEntity = entry.Entity as IGeneratesDomainEvents;
            if (generatesDomainEventsEntity == null)
            {
                continue;
            }

            // 实体或聚合根里获取 LocalEvents
            var localEvents = generatesDomainEventsEntity.GetLocalEvents()?.ToArray();

            if (localEvents != null && localEvents.Any())
            {

                eventReport.DomainEvents.AddRange(
                    localEvents.Select(
                        eventRecord => new DomainEventEntry(
                            entry.Entity,
                            eventRecord.EventData,
                            eventRecord.EventOrder
                        )
                    )
                );
                //清除实体或聚合根里获取 LocalEvents
                generatesDomainEventsEntity.ClearLocalEvents();
            }

            var distributedEvents = generatesDomainEventsEntity.GetDistributedEvents()?.
            ToArray();
            if (distributedEvents != null && distributedEvents.Any())
            {
                eventReport.DistributedEvents.AddRange(
                    distributedEvents.Select(
                        eventRecord => new DomainEventEntry(
                            entry.Entity,
                            eventRecord.EventData,
                            eventRecord.EventOrder)
                    )
                );
                generatesDomainEventsEntity.ClearDistributedEvents();
            }
        }

        return eventReport;
    }


    // 处理实体的属性是扩展属性的
    protected virtual void HandleExtraPropertiesOnSave(EntityEntry entry)
    {
        //删除或没有修改的实体不处理
        if (entry.State.IsIn(EntityState.Deleted, EntityState.Unchanged))
        {
            return;
        }

        // 新增或修改的实体
        var entityType = entry.Metadata.ClrType;
        if (entityType == null)
        {
            return;
        }
        // 不是扩展属性不处理
        if (!(entry.Entity is IHasExtraProperties entity))
        {
            return;
        }

        //获取 entityType 绑定过的  ObjectExtensionInfo
        var objectExtension = ObjectExtensionManager.Instance.GetOrNull(entityType);
        if (objectExtension == null)
        {
            return;
        }

        //  属性  ObjectExtensionPropertyInfo 的   Configuration  配置过  EfCoreMapping
        var efMappedProperties = ObjectExtensionManager.Instance
            .GetProperties(entityType)
            .Where(p => p.IsMappedToFieldForEfCore());

        // ObjectExtensionPropertyInfo
        foreach (var property in efMappedProperties)
        {
            //实体有此配置属性
            if (!entity.HasProperty(property.Name))
            {
                continue;
            }

            //获取的是数据库模型的属性
            var entryProperty = entry.Property(property.Name);

            //获取的是扩展对象的属性
            var entityProperty = entity.GetProperty(property.Name);

            //扩展属性没有值
            if (entityProperty == null)
            {
                //数据库模型对象默认也给  null
                entryProperty.CurrentValue = null;
                continue;
            }

            //类型相等就把扩展属性的值赋给数据库模型
            if (entryProperty.Metadata.ClrType == entityProperty.GetType())
            {
                entryProperty.CurrentValue = entityProperty;
            }
            //属性的类型不相等
            else
            {
                // 是私有类型 或 datetime  guid  decimal
                if (TypeHelper.IsPrimitiveExtended(entryProperty.Metadata.ClrType,
                includeEnums: true))
                {
                    var conversionType = entryProperty.Metadata.ClrType;
                    if (TypeHelper.IsNullable(conversionType))
                    {
                        conversionType = conversionType.
                        GetFirstGenericArgumentIfNullable();
                    }

                    if (conversionType == typeof(Guid))
                    {
                        entryProperty.CurrentValue = TypeDescriptor.GetConverter(
                          conversionType).ConvertFromInvariantString(
                            entityProperty.ToString()!);
                    }
                    else if (conversionType.IsEnum)
                    {
                        entryProperty.CurrentValue = Enum.Parse(conversionType,
                        entityProperty.ToString()!, ignoreCase: true);
                    }
                    else
                    {
                        entryProperty.CurrentValue = Convert.ChangeType(
                          entityProperty, conversionType, CultureInfo.InvariantCulture);
                    }
                }
            }
        }
    }

    //在实体增加的时候, 给 继承相应接口的实体相应属性的赋值
    protected virtual void ApplyAbpConceptsForAddedEntity(EntityEntry entry)
    {
        //在实体被新增的时候,在不是数据库新增的情况下,生成新的 id
        CheckAndSetId(entry);
        //在实体被新增的时候,设置并发属性的值
        SetConcurrencyStampIfNull(entry);
        //如果实体继承了 audit 接口,给这些接口相应字段赋值
        SetCreationAuditProperties(entry);
    }

    // 在实体修改或软删除的时候, 给 继承相应接口的实体相应属性的赋值
    protected virtual void ApplyAbpConceptsForModifiedEntity(EntityEntry entry)
    {
        if (entry.State == EntityState.Modified && entry.Properties.Any(x => x.IsModified
         && (x.Metadata.ValueGenerated == ValueGenerated.Never ||
          x.Metadata.ValueGenerated == ValueGenerated.OnAdd)))
        {
            IncrementEntityVersionProperty(entry);
            SetModificationAuditProperties(entry);

            if (entry.Entity is ISoftDelete && entry.Entity.As<ISoftDelete>().IsDeleted)
            {
                SetDeletionAuditProperties(entry);
            }
        }
    }

    //删除的时候,设置一些属性
    protected virtual void ApplyAbpConceptsForDeletedEntity(EntityEntry entry)
    {
        if (!(entry.Entity is ISoftDelete))
        {
            return;
        }

        if (IsHardDeleted(entry))
        {
            return;
        }

        entry.Reload();
        ObjectHelper.TrySetProperty(entry.Entity.As<ISoftDelete>(),
        x => x.IsDeleted, () => true);
        SetDeletionAuditProperties(entry);
    }

    //硬删除
    protected virtual bool IsHardDeleted(EntityEntry entry)
    {
        var hardDeletedEntities = UnitOfWorkManager?.Current?.Items.
        GetOrDefault(UnitOfWorkItemNames.HardDeletedEntities) as HashSet<IEntity>;
        if (hardDeletedEntities == null)
        {
            return false;
        }

        return hardDeletedEntities.Contains(entry.Entity);
    }

    //更新并发值
    protected virtual void UpdateConcurrencyStamp(EntityEntry entry)
    {
        var entity = entry.Entity as IHasConcurrencyStamp;
        if (entity == null)
        {
            return;
        }

        Entry(entity).Property(x => x.ConcurrencyStamp).OriginalValue =
         entity.ConcurrencyStamp;
        entity.ConcurrencyStamp = Guid.NewGuid().ToString("N");
    }

    protected virtual void SetConcurrencyStampIfNull(EntityEntry entry)
    {
        var entity = entry.Entity as IHasConcurrencyStamp;
        if (entity == null)
        {
            return;
        }

        if (entity.ConcurrencyStamp != null)
        {
            return;
        }

        entity.ConcurrencyStamp = Guid.NewGuid().ToString("N");
    }

    //设置 id
    protected virtual void CheckAndSetId(EntityEntry entry)
    {
        if (entry.Entity is IEntity<Guid> entityWithGuidId)
        {
            TrySetGuidId(entry, entityWithGuidId);
        }
    }

    protected virtual void TrySetGuidId(EntityEntry entry, IEntity<Guid> entity)
    {
        if (entity.Id != default)
        {
            return;
        }

        var idProperty = entry.Property("Id").Metadata.PropertyInfo!;

        //Check for DatabaseGeneratedAttribute
        var dbGeneratedAttr = ReflectionHelper
            .GetSingleAttributeOrDefault<DatabaseGeneratedAttribute>(
                idProperty
            );

        if (dbGeneratedAttr != null && dbGeneratedAttr.DatabaseGeneratedOption !=
         DatabaseGeneratedOption.None)
        {
            return;
        }

        EntityHelper.TrySetId(
            entity,
            () => GuidGenerator.Create(),
            true
        );
    }

    protected virtual void SetCreationAuditProperties(EntityEntry entry)
    {
        AuditPropertySetter?.SetCreationProperties(entry.Entity);
    }

    protected virtual void SetModificationAuditProperties(EntityEntry entry)
    {
        AuditPropertySetter?.SetModificationProperties(entry.Entity);
    }

    protected virtual void SetDeletionAuditProperties(EntityEntry entry)
    {
        AuditPropertySetter?.SetDeletionProperties(entry.Entity);
    }

    protected virtual void IncrementEntityVersionProperty(EntityEntry entry)
    {
        AuditPropertySetter?.IncrementEntityVersionProperty(entry.Entity);
    }

    //约定的配置属性 审计里的属性, 并发标记
    protected virtual void ConfigureBaseProperties<TEntity>(ModelBuilder modelBuilder,
     IMutableEntityType mutableEntityType)
        where TEntity : class
    {
        if (mutableEntityType.IsOwned())
        {
            return;
        }

        if (!typeof(IEntity).IsAssignableFrom(typeof(TEntity)))
        {
            return;
        }

        modelBuilder.Entity<TEntity>().ConfigureByConvention();

        ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType);
    }

    //配置全局过滤器
    protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder,
    IMutableEntityType mutableEntityType)
        where TEntity : class
    {
        //实体继承了相应的过滤器
        if (mutableEntityType.BaseType == null && ShouldFilterEntity<TEntity>(
          mutableEntityType))
        {
            var filterExpression = CreateFilterExpression<TEntity>();
            if (filterExpression != null)
            {
                //对实体加全局过滤器,abp 定义的过滤器都是查询过滤器
                modelBuilder.Entity<TEntity>().HasAbpQueryFilter(filterExpression);
            }
        }
    }

    // 配置默认的值转换程序  abp 默认就  data time 类型有值转换程序
    protected virtual void ConfigureValueConverter<TEntity>(ModelBuilder modelBuilder,
    IMutableEntityType mutableEntityType)
        where TEntity : class
    {
        if (mutableEntityType.BaseType == null &&
            !typeof(TEntity).IsDefined(typeof(DisableDateTimeNormalizationAttribute),
             true) &&
            !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) &&
            !mutableEntityType.IsOwned())
        {
            if (LazyServiceProvider == null || Clock == null)
            {
                return;
            }

            foreach (var property in mutableEntityType.GetProperties().
                         Where(property => property.PropertyInfo != null &&
                        (property.PropertyInfo.PropertyType ==
                        typeof(DateTime) ||
                        property.PropertyInfo.PropertyType == typeof(DateTime?)) &&
                        property.PropertyInfo.CanWrite &&
                        ReflectionHelper.
                        GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<
                        DisableDateTimeNormalizationAttribute>(
                          property.PropertyInfo) == null))
            {
				modelBuilder
                    .Entity<TEntity>()
                    .Property(property.Name)
                    .HasConversion(property.ClrType == typeof(DateTime)
                        ? new AbpDateTimeValueConverter(Clock)
                        : new AbpNullableDateTimeValueConverter(Clock));
            }
        }
    }

    // guid 的主键不要用 数据库生成
    protected virtual void ConfigureValueGenerated<TEntity>(ModelBuilder modelBuilder,
    IMutableEntityType mutableEntityType)
        where TEntity : class
    {
        // 不是 IEntity<Guid> 类型
        if (!typeof(IEntity<Guid>).IsAssignableFrom(typeof(TEntity)))
        {
            return;
        }

        // 是 IEntity<Guid> 类型,但是 Id 属性明确是由数据库生成
        var idPropertyBuilder = modelBuilder.Entity<TEntity>().
        Property(x => ((IEntity<Guid>)x).Id);
        if (idPropertyBuilder.Metadata.PropertyInfo!.
        IsDefined(typeof(DatabaseGeneratedAttribute), true))
        {
            return;
        }

        // IEntity<Guid> 的 ID 明确告诉数据库不要生成,由程序生成
        idPropertyBuilder.ValueGeneratedNever();
    }

    //实体是否能被使用过滤器
    protected virtual bool ShouldFilterEntity<TEntity>(
      IMutableEntityType entityType) where TEntity : class
    {
        if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
        {
            return true;
        }

        if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
        {
            return true;
        }

        return false;
    }

    //
    protected virtual Expression<Func<TEntity, bool>>?
    CreateFilterExpression<TEntity>()
        where TEntity : class
    {
        Expression<Func<TEntity, bool>>? expression = null;

        if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
        {
            expression = e => !IsSoftDeleteFilterEnabled ||
            !EF.Property<bool>(e, "IsDeleted");
        }

        if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
        {
            Expression<Func<TEntity, bool>> multiTenantFilter = e =>
             !IsMultiTenantFilterEnabled ||
              EF.Property<Guid>(e, "TenantId") == CurrentTenantId;
            expression = expression == null ? multiTenantFilter :
            QueryFilterExpressionHelper.CombineExpressions(expression, multiTenantFilter);
        }

        return expression;
    }
}

AbpEntityTypeBuilderExtensions 实体的约定配置

public static class AbpEntityTypeBuilderExtensions
{
    public static void ConfigureByConvention(this EntityTypeBuilder b)
    {
        //配置并发标记,数据库字段长度
        b.TryConfigureConcurrencyStamp();
        // 额外的属性,序列化为json 保存到数据库 ,实体需要实现 IHasExtraProperties 接口,
        //并且额外的属性保存在固定的
        // ExtraPropertyDictionary 字段里
        b.TryConfigureExtraProperties();
        // 额外的属性,在数据库里保存为单独的指定数据类型的字段
        // 这个是 EF 里的影子属性
        // 也需要 实体需要实现 IHasExtraProperties 接口
        b.TryConfigureObjectExtensions();

        //以下都是为审计设置属性在数据库必须等属性
        b.TryConfigureMayHaveCreator();
        b.TryConfigureMustHaveCreator();
        b.TryConfigureSoftDelete();
        b.TryConfigureDeletionTime();
        b.TryConfigureDeletionAudited();
        b.TryConfigureCreationTime();
        b.TryConfigureLastModificationTime();
        b.TryConfigureModificationAudited();
        // 设置租户  数据库 Required
        b.TryConfigureMultiTenant();
    }

    public static void ConfigureConcurrencyStamp<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasConcurrencyStamp
    {
        b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
    }

    public static void TryConfigureConcurrencyStamp(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasConcurrencyStamp>())
        {
            b.Property(nameof(IHasConcurrencyStamp.ConcurrencyStamp))
                .IsConcurrencyToken()
                .HasMaxLength(ConcurrencyStampConsts.MaxLength)
                .HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp));
        }
    }

    public static void ConfigureExtraProperties<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasExtraProperties
    {
        b.As<EntityTypeBuilder>().TryConfigureExtraProperties();
    }

    public static void TryConfigureExtraProperties(this EntityTypeBuilder b)
    {
        if (!b.Metadata.ClrType.IsAssignableTo<IHasExtraProperties>())
        {
            return;
        }

        b.Property<ExtraPropertyDictionary>(nameof(IHasExtraProperties.ExtraProperties))
            .HasColumnName(nameof(IHasExtraProperties.ExtraProperties))
            .HasConversion(new ExtraPropertiesValueConverter(b.Metadata.ClrType))
            .Metadata.SetValueComparer(new ExtraPropertyDictionaryValueComparer());

        b.TryConfigureObjectExtensions();
    }

    public static void ConfigureObjectExtensions<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasExtraProperties
    {
        b.As<EntityTypeBuilder>().TryConfigureObjectExtensions();
    }

    public static void TryConfigureObjectExtensions(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasExtraProperties>())
        {
            ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b);
        }
    }

    public static void ApplyObjectExtensionMappings(this EntityTypeBuilder b)
    {
        ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b);
    }

    public static void ConfigureSoftDelete<T>(this EntityTypeBuilder<T> b)
        where T : class, ISoftDelete
    {
        b.As<EntityTypeBuilder>().TryConfigureSoftDelete();
    }

    public static void TryConfigureSoftDelete(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<ISoftDelete>())
        {
            b.Property(nameof(ISoftDelete.IsDeleted))
                .IsRequired()
                .HasDefaultValue(false)
                .HasColumnName(nameof(ISoftDelete.IsDeleted));
        }
    }

    public static void ConfigureDeletionTime<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasDeletionTime
    {
        b.As<EntityTypeBuilder>().TryConfigureDeletionTime();
    }

    public static void TryConfigureDeletionTime(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasDeletionTime>())
        {
            b.TryConfigureSoftDelete();

            b.Property(nameof(IHasDeletionTime.DeletionTime))
                .IsRequired(false)
                .HasColumnName(nameof(IHasDeletionTime.DeletionTime));
        }
    }

    public static void ConfigureMayHaveCreator<T>(this EntityTypeBuilder<T> b)
        where T : class, IMayHaveCreator
    {
        b.As<EntityTypeBuilder>().TryConfigureMayHaveCreator();
    }

    public static void TryConfigureMayHaveCreator(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IMayHaveCreator>())
        {
            b.Property(nameof(IMayHaveCreator.CreatorId))
                .IsRequired(false)
                .HasColumnName(nameof(IMayHaveCreator.CreatorId));
        }
    }

    public static void ConfigureMustHaveCreator<T>(this EntityTypeBuilder<T> b)
        where T : class, IMustHaveCreator
    {
        b.As<EntityTypeBuilder>().TryConfigureMustHaveCreator();
    }

    public static void TryConfigureMustHaveCreator(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IMustHaveCreator>())
        {
            b.Property(nameof(IMustHaveCreator.CreatorId))
                .IsRequired()
                .HasColumnName(nameof(IMustHaveCreator.CreatorId));
        }
    }

    public static void ConfigureDeletionAudited<T>(this EntityTypeBuilder<T> b)
        where T : class, IDeletionAuditedObject
    {
        b.As<EntityTypeBuilder>().TryConfigureDeletionAudited();
    }

    public static void TryConfigureDeletionAudited(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IDeletionAuditedObject>())
        {
            b.TryConfigureDeletionTime();

            b.Property(nameof(IDeletionAuditedObject.DeleterId))
                .IsRequired(false)
                .HasColumnName(nameof(IDeletionAuditedObject.DeleterId));
        }
    }

    public static void ConfigureCreationTime<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasCreationTime
    {
        b.As<EntityTypeBuilder>().TryConfigureCreationTime();
    }

    public static void TryConfigureCreationTime(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasCreationTime>())
        {
            b.Property(nameof(IHasCreationTime.CreationTime))
                .IsRequired()
                .HasColumnName(nameof(IHasCreationTime.CreationTime));
        }
    }

    public static void ConfigureCreationAudited<T>(this EntityTypeBuilder<T> b)
        where T : class, ICreationAuditedObject
    {
        b.As<EntityTypeBuilder>().TryConfigureCreationAudited();
    }

    public static void TryConfigureCreationAudited(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<ICreationAuditedObject>())
        {
            b.As<EntityTypeBuilder>().TryConfigureCreationTime();
            b.As<EntityTypeBuilder>().TryConfigureMayHaveCreator();
        }
    }

    public static void ConfigureLastModificationTime<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasModificationTime
    {
        b.As<EntityTypeBuilder>().TryConfigureLastModificationTime();
    }

    public static void TryConfigureLastModificationTime(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasModificationTime>())
        {
            b.Property(nameof(IHasModificationTime.LastModificationTime))
                .IsRequired(false)
                .HasColumnName(nameof(IHasModificationTime.LastModificationTime));
        }
    }

    public static void ConfigureModificationAudited<T>(this EntityTypeBuilder<T> b)
        where T : class, IModificationAuditedObject
    {
        b.As<EntityTypeBuilder>().TryConfigureModificationAudited();
    }

    public static void TryConfigureModificationAudited(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IModificationAuditedObject>())
        {
            b.TryConfigureLastModificationTime();

            b.Property(nameof(IModificationAuditedObject.LastModifierId))
                .IsRequired(false)
                .HasColumnName(nameof(IModificationAuditedObject.LastModifierId));
        }
    }

    public static void ConfigureAudited<T>(this EntityTypeBuilder<T> b)
        where T : class, IAuditedObject
    {
        b.As<EntityTypeBuilder>().TryConfigureAudited();
    }

    public static void TryConfigureAudited(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IAuditedObject>())
        {
            b.As<EntityTypeBuilder>().TryConfigureCreationAudited();
            b.As<EntityTypeBuilder>().TryConfigureModificationAudited();
        }
    }

    public static void ConfigureFullAudited<T>(this EntityTypeBuilder<T> b)
        where T : class, IFullAuditedObject
    {
        b.As<EntityTypeBuilder>().TryConfigureFullAudited();
    }

    public static void TryConfigureFullAudited(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IFullAuditedObject>())
        {
            b.As<EntityTypeBuilder>().TryConfigureAudited();
            b.As<EntityTypeBuilder>().TryConfigureDeletionAudited();
        }
    }

    public static void ConfigureMultiTenant<T>(this EntityTypeBuilder<T> b)
        where T : class, IMultiTenant
    {
        b.As<EntityTypeBuilder>().TryConfigureMultiTenant();
    }

    public static void TryConfigureMultiTenant(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IMultiTenant>())
        {
            b.Property(nameof(IMultiTenant.TenantId))
                .IsRequired(false)
                .HasColumnName(nameof(IMultiTenant.TenantId));
        }
    }

    public static void ConfigureCreationAuditedAggregateRoot<T>(this
     EntityTypeBuilder<T> b)
        where T : class
    {
        b.As<EntityTypeBuilder>().TryConfigureCreationAudited();
        b.As<EntityTypeBuilder>().TryConfigureExtraProperties();
        b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
    }

    public static void ConfigureAuditedAggregateRoot<T>(this EntityTypeBuilder<T> b)
        where T : class
    {
        b.As<EntityTypeBuilder>().TryConfigureAudited();
        b.As<EntityTypeBuilder>().TryConfigureExtraProperties();
        b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
    }

    public static void ConfigureFullAuditedAggregateRoot<T>(this EntityTypeBuilder<T> b)
        where T : class
    {
        b.As<EntityTypeBuilder>().TryConfigureFullAudited();
        b.As<EntityTypeBuilder>().TryConfigureExtraProperties();
        b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
    }

    //TODO: Add other interfaces (IAuditedObject<TUser>...)
}

通过配置生成 AbpDbContext

AbpDbContextOptions AbpDbContext 配置选项

AbpDbContextConfigurationContext 配置上下文,提供能配置的条目

public class AbpDbContextConfigurationContext : IServiceProviderAccessor
{
    public IServiceProvider ServiceProvider { get; }

    //连接字符串
    public string ConnectionString { get; }

    public string? ConnectionStringName { get; }
    // ef 数据库连接
    public DbConnection? ExistingConnection { get; }

    // ef 数据库连接选项进行配置
    public DbContextOptionsBuilder DbContextOptions { get; protected set; }

    public AbpDbContextConfigurationContext(
        [NotNull] string connectionString,
        [NotNull] IServiceProvider serviceProvider,
        string? connectionStringName,
        DbConnection? existingConnection)
    {
        ConnectionString = connectionString;
        ServiceProvider = serviceProvider;
        ConnectionStringName = connectionStringName;
        ExistingConnection = existingConnection;

        DbContextOptions = new DbContextOptionsBuilder()
            .UseLoggerFactory(serviceProvider.GetRequiredService<ILoggerFactory>())
            .UseApplicationServiceProvider(serviceProvider);
    }
}

//  带 TDbContext 上下文的配置选项

public class AbpDbContextConfigurationContext<TDbContext> :
AbpDbContextConfigurationContext
    where TDbContext : AbpDbContext<TDbContext>
{
    public new DbContextOptionsBuilder<TDbContext> DbContextOptions =>
    (DbContextOptionsBuilder<TDbContext>)base.DbContextOptions;

    public AbpDbContextConfigurationContext(
        string connectionString,
        [NotNull] IServiceProvider serviceProvider,
        string? connectionStringName,
        DbConnection? existingConnection)
        : base(
              connectionString,
              serviceProvider,
              connectionStringName,
              existingConnection)
    {
        base.DbContextOptions = new DbContextOptionsBuilder<TDbContext>()
            .UseLoggerFactory(serviceProvider.GetRequiredService<ILoggerFactory>())
            .UseApplicationServiceProvider(serviceProvider); ;
    }
}

AbpDbContextOptions AbpDbContext 配置选项

此类主要时在数据库提供程序实现者里使用,EF CORE MYSQL 里使用此类生成 AbpDbContext

public class AbpDbContextOptions
{
    //在生成 AbpDbContextOptions 前执行的行为
    internal List<Action<AbpDbContextConfigurationContext>>
     DefaultPreConfigureActions { get; }
    // 在生成 AbpDbContextOptions 时 执行的行为
    internal Action<AbpDbContextConfigurationContext>?
     DefaultConfigureAction { get; set; }
    //在生成 AbpDbContextOptions 前执行的行为, 保存  TDbContext 的配置行为
    internal Dictionary<Type, List<object>> PreConfigureActions { get; }
    // 在生成 AbpDbContextOptions 时 执行的行为,保存  TDbContext 的配置行为
    internal Dictionary<Type, object> ConfigureActions { get; }

    //租户 和  DbContext 的对于关系,不同的租户可以有不同的  DbContext
    internal Dictionary<MultiTenantDbContextType, Type> DbContextReplacements { get; }

    public AbpDbContextOptions()
    {
        DefaultPreConfigureActions = new List<Action<AbpDbContextConfigurationContext>>();
        PreConfigureActions = new Dictionary<Type, List<object>>();
        ConfigureActions = new Dictionary<Type, object>();
        DbContextReplacements = new Dictionary<MultiTenantDbContextType, Type>();
    }

    public void PreConfigure([NotNull] Action<AbpDbContextConfigurationContext> action)
    {
        Check.NotNull(action, nameof(action));

        DefaultPreConfigureActions.Add(action);
    }

    public void Configure([NotNull] Action<AbpDbContextConfigurationContext> action)
    {
        Check.NotNull(action, nameof(action));

        DefaultConfigureAction = action;
    }

    public bool IsConfiguredDefault()
    {
        return DefaultConfigureAction != null;
    }

    public void PreConfigure<TDbContext>(
      [NotNull] Action<AbpDbContextConfigurationContext<TDbContext>> action)
        where TDbContext : AbpDbContext<TDbContext>
    {
        Check.NotNull(action, nameof(action));

        var actions = PreConfigureActions.GetOrDefault(typeof(TDbContext));
        if (actions == null)
        {
            PreConfigureActions[typeof(TDbContext)] = actions = new List<object>();
        }

        actions.Add(action);
    }

    public void Configure<TDbContext>(
      [NotNull] Action<AbpDbContextConfigurationContext<TDbContext>> action)
        where TDbContext : AbpDbContext<TDbContext>
    {
        Check.NotNull(action, nameof(action));

        ConfigureActions[typeof(TDbContext)] = action;
    }

    public bool IsConfigured<TDbContext>()
    {
        return IsConfigured(typeof(TDbContext));
    }

    public bool IsConfigured(Type dbContextType)
    {
        return ConfigureActions.ContainsKey(dbContextType);
    }

    // DbContextReplacements 里看有没有匹配的  dbContextType
    internal Type GetReplacedTypeOrSelf(
      Type dbContextType, MultiTenancySides multiTenancySides = MultiTenancySides.Both)
    {
        var replacementType = dbContextType;
        while (true)
        {
            //在预配置的服务里匹配可以换的  dbContextType
            var foundType = DbContextReplacements.
            LastOrDefault(
              x => x.Key.Type == replacementType &&
               x.Key.MultiTenancySide.HasFlag(multiTenancySides));

            if (!foundType.Equals(default(KeyValuePair<MultiTenantDbContextType, Type>)))
            {
                if (foundType.Value == dbContextType)
                {
                    throw new AbpException(
                        "Circular DbContext replacement found for " +
                        dbContextType.AssemblyQualifiedName
                    );
                }
                // 没找到继续找
                replacementType = foundType.Value;
            }
            else
            {
                //找到匹配的
                return replacementType;
            }
        }
    }
}

IDbContextProvider DbContextProvider 提供者

public interface IDbContextProvider<TDbContext>
    where TDbContext : IEfCoreDbContext
{
    Task<TDbContext> GetDbContextAsync();
}

ef core 实现工作单元内定义的接口

ef core 实现 ITransactionApi

public class EfCoreTransactionApi : ITransactionApi, ISupportsRollback
{
    public IDbContextTransaction DbContextTransaction { get; }
    public IEfCoreDbContext StarterDbContext { get; }
    public List<IEfCoreDbContext> AttendedDbContexts { get; }

    protected ICancellationTokenProvider CancellationTokenProvider { get; }

    public EfCoreTransactionApi(
        //使用数据库的事务提供器
        IDbContextTransaction dbContextTransaction,
        //数据库上下文
        IEfCoreDbContext starterDbContext,
        ICancellationTokenProvider cancellationTokenProvider)
    {
        DbContextTransaction = dbContextTransaction;
        StarterDbContext = starterDbContext;
        CancellationTokenProvider = cancellationTokenProvider;
        AttendedDbContexts = new List<IEfCoreDbContext>();
    }

    public async Task CommitAsync(CancellationToken cancellationToken = default)
    {
        foreach (var dbContext in AttendedDbContexts)
        {
            if (dbContext.As<DbContext>().HasRelationalTransactionManager() &&
                // DbContextTransaction.GetDbTransaction() 获取  DbTransaction
                // 当前数据库上下文使用的数据库连接和 当前开启的事务使用的数据库连接相同
                dbContext.Database.GetDbConnection() ==
                DbContextTransaction.GetDbTransaction().Connection)
            {
                continue;
                //Relational databases use the shared
                //transaction if they are using the same connection
            }
            //如果连接使用的事务不是当前的事务,对连接上的事务单独提交
            await dbContext.Database.CommitTransactionAsync(
              CancellationTokenProvider.FallbackToProvider(cancellationToken));
        }

        //当前的事务提交
        await DbContextTransaction.CommitAsync(
          CancellationTokenProvider.FallbackToProvider(cancellationToken));
    }

    public void Dispose()
    {
        DbContextTransaction.Dispose();
    }

    //回滚提交
    public async Task RollbackAsync(CancellationToken cancellationToken)
    {
        foreach (var dbContext in AttendedDbContexts)
        {
            if (dbContext.As<DbContext>().HasRelationalTransactionManager() &&
                dbContext.Database.GetDbConnection() ==
                DbContextTransaction.GetDbTransaction().Connection)
            {
                continue; //Relational databases use the
                // shared transaction if they are using the same connection
            }

            await dbContext.Database.RollbackTransactionAsync(
              CancellationTokenProvider.FallbackToProvider(cancellationToken));
        }

        await DbContextTransaction.RollbackAsync(
          CancellationTokenProvider.FallbackToProvider(cancellationToken));
    }
}

Ef Core 实现 IDatabaseApi

public class EfCoreDatabaseApi : IDatabaseApi, ISupportsSavingChanges
{
    public IEfCoreDbContext DbContext { get; }

    public EfCoreDatabaseApi(IEfCoreDbContext dbContext)
    {
        DbContext = dbContext;
    }

    public Task SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        return DbContext.SaveChangesAsync(cancellationToken);
    }
}

在工作单元内获取 IDbContext

为什么是工作单元获取事务,因为工作单元可以是事务性的,此事务可以在不同的数据库上下文之间 进行复用,只要使用的数据库链接时同样的

public class UnitOfWorkDbContextProvider<TDbContext> : IDbContextProvider<TDbContext>
    where TDbContext : IEfCoreDbContext
{
    private const string TransactionsNotSupportedWarningMessage =
     "Current database does not support transactions. Your
     database may remain in an inconsistent state in an error case.";

    public ILogger<UnitOfWorkDbContextProvider<TDbContext>> Logger { get; set; }

    protected readonly IUnitOfWorkManager UnitOfWorkManager;
    protected readonly IConnectionStringResolver ConnectionStringResolver;
    protected readonly ICancellationTokenProvider CancellationTokenProvider;
    protected readonly ICurrentTenant CurrentTenant;
    //获取当前的  EfCoreDbContextType 类型
    protected readonly IEfCoreDbContextTypeProvider EfCoreDbContextTypeProvider;

    public UnitOfWorkDbContextProvider(
        IUnitOfWorkManager unitOfWorkManager,
        IConnectionStringResolver connectionStringResolver,
        ICancellationTokenProvider cancellationTokenProvider,
        ICurrentTenant currentTenant,
        IEfCoreDbContextTypeProvider efCoreDbContextTypeProvider)
    {
        UnitOfWorkManager = unitOfWorkManager;
        ConnectionStringResolver = connectionStringResolver;
        CancellationTokenProvider = cancellationTokenProvider;
        CurrentTenant = currentTenant;
        EfCoreDbContextTypeProvider = efCoreDbContextTypeProvider;

        Logger = NullLogger<UnitOfWorkDbContextProvider<TDbContext>>.Instance;
    }


    public virtual async Task<TDbContext> GetDbContextAsync()
    {
        var unitOfWork = UnitOfWorkManager.Current;
        if (unitOfWork == null)
        {
            throw new AbpException(
              "A DbContext can only be created inside a unit of work!");
        }

        // 获取真实的 DbContextType,因为有可能被替换
        var targetDbContextType = EfCoreDbContextTypeProvider.
        GetDbContextType(typeof(TDbContext));
        // 获取链接字符串名
        var connectionStringName = ConnectionStringNameAttribute.
        GetConnStringName(targetDbContextType);
        // 获取链接字符串
        var connectionString = await ResolveConnectionStringAsync(connectionStringName);

        var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}";

        //因为 一个 unitOfWork 里可以有多个数据库上下文及其绑定的连接字符串,
        //这里获取要使用的 db context
        var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);

        if (databaseApi == null)
        {
            databaseApi = new EfCoreDatabaseApi(
                //生成数据库上下文
                await CreateDbContextAsync(unitOfWork,
                 connectionStringName, connectionString)
            );

            unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
        }

        return (TDbContext)((EfCoreDatabaseApi)databaseApi).DbContext;
    }

    //
    protected virtual async Task<TDbContext> CreateDbContextAsync(
      IUnitOfWork unitOfWork, string connectionStringName, string connectionString)
    {
        //
        var creationContext = new DbContextCreationContext(
          connectionStringName, connectionString);

        //使用 creationContext 的值临时替换  DbContextCreationContext 的 当前值
        //结束的时候恢复之前的值
        using (DbContextCreationContext.Use(creationContext))
        {
            //  生成一个数据库上下文,此上下文时瞬死的,数据库上下文可以复用事务
            var dbContext = await CreateDbContextAsync(unitOfWork);

            if (dbContext is IAbpEfCoreDbContext abpEfCoreDbContext)
            {
                //设置生成的数据库上下文的工作单元为当前

                abpEfCoreDbContext.Initialize(
                    new AbpEfCoreDbContextInitializationContext(
                        unitOfWork
                    )
                );
            }

            return dbContext;
        }
    }

    //获取数据库上下文
    protected virtual async Task<TDbContext> CreateDbContextAsync(IUnitOfWork unitOfWork)
    {
        return unitOfWork.Options.IsTransactional
            ? await CreateDbContextWithTransactionAsync(unitOfWork)
            : unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();
    }

    //生成事务的 DbContext
    protected virtual async Task<TDbContext>
     CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
    {
        var transactionApiKey = $"EntityFrameworkCore_{
          DbContextCreationContext.Current.ConnectionString}";
        //判断工作单元内是否有存在的指定的事务,依据连接字符串
        var activeTransaction = unitOfWork.FindTransactionApi(
          transactionApiKey) as EfCoreTransactionApi;

        if (activeTransaction == null)
        {
            //服务定位器获得当前的数据库上下文,此上下文时瞬时的
            var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();

            try
            {
                //  生成一个  IDbContextTransaction
                var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? await dbContext.Database.BeginTransactionAsync(
                      unitOfWork.Options.IsolationLevel.Value, GetCancellationToken())
                    : await dbContext.Database.BeginTransactionAsync(
                      GetCancellationToken());

                //利用生成的数据库上下文,生成事务,并把此事务保存到此工作单元内
                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbTransaction,
                        dbContext,
                        CancellationTokenProvider
                    )
                );
            }
            catch (Exception e) when (e is InvalidOperationException ||
            e is NotSupportedException)
            {
                Logger.LogWarning(TransactionsNotSupportedWarningMessage);

                return dbContext;
            }

            return dbContext;
        }
        else
        {
            //数据库连接上下文里更换连接到当前工作单元内存在的事务
            DbContextCreationContext.Current.ExistingConnection =
             activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

            //获取上下文
            var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();

            if (dbContext.As<DbContext>().HasRelationalTransactionManager())
            {
                if (dbContext.Database.GetDbConnection() ==
                 DbContextCreationContext.Current.ExistingConnection)
                {
                    //更改当前数据库上下文的事务为当前工作单元内激活的事务
                    await dbContext.Database.UseTransactionAsync(
                      activeTransaction.DbContextTransaction.GetDbTransaction(),
                       GetCancellationToken());
                }
                else
                {
                    try
                    {
                        /* User did not re-use the ExistingConnection and we
                          are starting a new transaction.
                          EfCoreTransactionApi will check the connection
                          string match and separately
                          commit/rollback this transaction
                          over the DbContext instance. */
                        if (unitOfWork.Options.IsolationLevel.HasValue)
                        {
                            await dbContext.Database.BeginTransactionAsync(
                                unitOfWork.Options.IsolationLevel.Value,
                                GetCancellationToken()
                            );
                        }
                        else
                        {
                            await dbContext.Database.BeginTransactionAsync(
                                GetCancellationToken()
                            );
                        }
                    }
                    catch (Exception e) when (e is InvalidOperationException ||
                     e is NotSupportedException)
                    {
                        Logger.LogWarning(TransactionsNotSupportedWarningMessage);

                        return dbContext;
                    }
                }
            }
            else
            {
                try
                {
                    /* No need to store the returning IDbContextTransaction
                     for non-relational databases
                        * since EfCoreTransactionApi will handle the
                        commit/rollback over the DbContext instance.
                          */

                    //  EfCoreTransactionApi  非关系性数据库的事务没有提交等
                    api 不需要进行保存到字典

                    await dbContext.Database.BeginTransactionAsync(
                      GetCancellationToken());
                }
                catch (Exception e) when (e is InvalidOperationException
                 || e is NotSupportedException)
                {
                    Logger.LogWarning(TransactionsNotSupportedWarningMessage);

                    return dbContext;
                }
            }

            activeTransaction.AttendedDbContexts.Add(dbContext);

            return dbContext;
        }
    }

    //获取当前的连接字符串
    protected virtual async Task<string> ResolveConnectionStringAsync(
      string connectionStringName)
    {
        // Multi-tenancy unaware contexts should always use the host connection string
        if (typeof(TDbContext).IsDefined(typeof(IgnoreMultiTenancyAttribute), false))
        {
            using (CurrentTenant.Change(null))
            {
                return await ConnectionStringResolver.ResolveAsync(connectionStringName);
            }
        }

        return await ConnectionStringResolver.ResolveAsync(connectionStringName);
    }


    protected virtual CancellationToken GetCancellationToken(
      CancellationToken preferredValue = default)
    {
        return CancellationTokenProvider.FallbackToProvider(preferredValue);
    }
}

并发标记的配置

    public static void ConfigureConcurrencyStamp<T>(this EntityTypeBuilder<T> b)
        where T : class, IHasConcurrencyStamp
    {
        b.As<EntityTypeBuilder>().TryConfigureConcurrencyStamp();
    }

    public static void TryConfigureConcurrencyStamp(this EntityTypeBuilder b)
    {
        if (b.Metadata.ClrType.IsAssignableTo<IHasConcurrencyStamp>())
        {
            b.Property(nameof(IHasConcurrencyStamp.ConcurrencyStamp))
                .IsConcurrencyToken()
                .HasMaxLength(ConcurrencyStampConsts.MaxLength)
                .HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp));
        }
    }

BasicRepositoryBase 仓储最基础的实现类

using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Linq;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Uow;

namespace Volo.Abp.Domain.Repositories;

//IUnitOfWorkEnabled  仓储本身方法是工作单元
public abstract class BasicRepositoryBase<TEntity> :
    IBasicRepository<TEntity>,
    IServiceProviderAccessor,
    IUnitOfWorkEnabled
    where TEntity : class, IEntity
{
    public IAbpLazyServiceProvider LazyServiceProvider { get; set; }

    public IServiceProvider ServiceProvider { get; set; }

    public IDataFilter DataFilter =>
     LazyServiceProvider.LazyGetRequiredService<IDataFilter>();

    public ICurrentTenant CurrentTenant =>
     LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();

    public IAsyncQueryableExecuter AsyncExecuter =>
     LazyServiceProvider.LazyGetRequiredService<IAsyncQueryableExecuter>();

    public IUnitOfWorkManager UnitOfWorkManager =>
     LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();

    public ICancellationTokenProvider CancellationTokenProvider =>
     LazyServiceProvider.LazyGetService<ICancellationTokenProvider>
     (NullCancellationTokenProvider.Instance);

    protected BasicRepositoryBase()
    {

    }

    public abstract Task<TEntity> InsertAsync(TEntity entity,
     bool autoSave = false, CancellationToken cancellationToken = default);

    public virtual async Task InsertManyAsync(IEnumerable<TEntity> entities,
    bool autoSave = false, CancellationToken cancellationToken = default)
    {
        foreach (var entity in entities)
        {
            await InsertAsync(entity, cancellationToken: cancellationToken);
        }

        if (autoSave)
        {
            await SaveChangesAsync(cancellationToken);
        }
    }

    protected virtual Task SaveChangesAsync(CancellationToken cancellationToken)
    {
        if (UnitOfWorkManager?.Current != null)
        {
            return UnitOfWorkManager.Current.SaveChangesAsync(cancellationToken);
        }

        return Task.CompletedTask;
    }

    public abstract Task<TEntity> UpdateAsync(TEntity entity, bool autoSave =
     false, CancellationToken cancellationToken = default);

    public virtual async Task UpdateManyAsync(IEnumerable<TEntity> entities,
    bool autoSave = false, CancellationToken cancellationToken = default)
    {
        foreach (var entity in entities)
        {
            await UpdateAsync(entity, cancellationToken: cancellationToken);
        }

        if (autoSave)
        {
            await SaveChangesAsync(cancellationToken);
        }
    }

    public abstract Task DeleteAsync(TEntity entity, bool autoSave =
     false, CancellationToken cancellationToken = default);

    public virtual async Task DeleteManyAsync(IEnumerable<TEntity> entities,
     bool autoSave = false, CancellationToken cancellationToken = default)
    {
        foreach (var entity in entities)
        {
            await DeleteAsync(entity, cancellationToken: cancellationToken);
        }

        if (autoSave)
        {
            await SaveChangesAsync(cancellationToken);
        }
    }

    public abstract Task<List<TEntity>> GetListAsync(
      bool includeDetails = false, CancellationToken cancellationToken = default);

    public abstract Task<List<TEntity>> GetListAsync(
      Expression<Func<TEntity, bool>> predicate, bool includeDetails =
      false, CancellationToken cancellationToken = default);

    public abstract Task<long> GetCountAsync(CancellationToken cancellationToken = default);

    public abstract Task<List<TEntity>> GetPagedListAsync(
      int skipCount, int maxResultCount, string sorting, bool includeDetails =
       false, CancellationToken cancellationToken = default);

    protected virtual CancellationToken GetCancellationToken(
      CancellationToken preferredValue = default)
    {
        return CancellationTokenProvider.FallbackToProvider(preferredValue);
    }
}

public abstract class BasicRepositoryBase<TEntity, TKey> :
 BasicRepositoryBase<TEntity>, IBasicRepository<TEntity, TKey>
    where TEntity : class, IEntity<TKey>
{
    public virtual async Task<TEntity> GetAsync(
      TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
    {
        var entity = await FindAsync(id, includeDetails, cancellationToken);

        if (entity == null)
        {
            throw new EntityNotFoundException(typeof(TEntity), id);
        }

        return entity;
    }

    public abstract Task<TEntity> FindAsync(
      TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);

    public virtual async Task DeleteAsync(
      TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
    {
        var entity = await FindAsync(id, cancellationToken: cancellationToken);
        if (entity == null)
        {
            return;
        }

        await DeleteAsync(entity, autoSave, cancellationToken);
    }

    public async Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave =
    false, CancellationToken cancellationToken = default)
    {
        foreach (var id in ids)
        {
            await DeleteAsync(id, cancellationToken: cancellationToken);
        }

        if (autoSave)
        {
            await SaveChangesAsync(cancellationToken);
        }
    }
}
👍🎉🎊