using Microsoft.EntityFrameworkCore; using ShardingCore.Extensions; using ShardingCore.Sharding.Abstractions; using System; using System.ComponentModel.DataAnnotations.Schema; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking; using ShardingCore.EFCores; using ShardingCore.Sharding.ShardingDbContextExecutors; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Reflection; namespace Samples.AbpSharding { public abstract class AbstractShardingAbpDbContext : AbpDbContext, IShardingDbContext where TDbContext : DbContext { private bool _createExecutor = false; protected AbstractShardingAbpDbContext(DbContextOptions options) : base(options) { } private IShardingDbContextExecutor _shardingDbContextExecutor; public IShardingDbContextExecutor GetShardingExecutor() { if (!_createExecutor) { _shardingDbContextExecutor=this.DoCreateShardingDbContextExecutor(); _createExecutor = true; } return _shardingDbContextExecutor; } private IShardingDbContextExecutor DoCreateShardingDbContextExecutor() { var shardingDbContextExecutor = this.CreateShardingDbContextExecutor(); if (shardingDbContextExecutor != null) { shardingDbContextExecutor.EntityCreateDbContextBefore += (sender, args) => { CheckAndSetShardingKeyThatSupportAutoCreate(args.Entity); }; shardingDbContextExecutor.CreateDbContextAfter += (sender, args) => { var dbContext = args.DbContext; if (dbContext is AbpDbContext abpDbContext && abpDbContext.LazyServiceProvider == null) { abpDbContext.LazyServiceProvider = this.LazyServiceProvider; if (dbContext is IAbpEfCoreDbContext abpEfCoreDbContext&&this.UnitOfWorkManager.Current!=null) { abpEfCoreDbContext.Initialize( new AbpEfCoreDbContextInitializationContext( this.UnitOfWorkManager.Current ) ); } } }; } return shardingDbContextExecutor; } private void CheckAndSetShardingKeyThatSupportAutoCreate(TEntity entity) where TEntity : class { if (entity is IShardingKeyIsGuId) { if (entity is IEntity guidEntity) { if (guidEntity.Id != default) { return; } var idProperty = entity.GetObjectProperty(nameof(IEntity.Id)); var dbGeneratedAttr = ReflectionHelper .GetSingleAttributeOrDefault( idProperty ); if (dbGeneratedAttr != null && dbGeneratedAttr.DatabaseGeneratedOption != DatabaseGeneratedOption.None) { return; } EntityHelper.TrySetId( guidEntity, () => GuidGenerator.Create(), true ); } } else if (entity is IShardingKeyIsCreationTime) { AuditPropertySetter?.SetCreationProperties(entity); } } // /// // /// abp 5.x+ 如果存在并发字段那么需要添加这段代码 // /// // protected override void HandlePropertiesBeforeSave() // { // if (GetShardingExecutor() == null) // { // base.HandlePropertiesBeforeSave(); // } // } // /// // /// abp 4.x+ 如果存在并发字段那么需要添加这段代码 // /// // /// // // protected override void ApplyAbpConcepts(EntityEntry entry, EntityChangeReport changeReport) // { // if (GetShardingExecutor() == null) // { // base.ApplyAbpConcepts(entry, changeReport); // } // } public override void Dispose() { _shardingDbContextExecutor?.Dispose(); base.Dispose(); } public override async ValueTask DisposeAsync() { if (_shardingDbContextExecutor != null) { await _shardingDbContextExecutor.DisposeAsync(); } await base.DisposeAsync(); } } }