/// <summary> /// 解析持久化模型。 /// </summary> /// <param name="dbContextAccessor">给定的数据库上下文访问器。</param> /// <returns>返回 <see cref="IModel"/>。</returns> protected virtual IModel ResolvePersistentModel (DataDbContextAccessor <TAudit, TAuditProperty, TMigration, TTabulation, TTenant, TGenId, TIncremId, TCreatedBy> dbContextAccessor) { return(ExtensionSettings.Preference.RunLocker(() => { var cacheKey = DbContextAccessorHelper.GetMigrationCacheKey(dbContextAccessor); return MemoryCache.GetOrCreate(cacheKey, entry => { Type snapshotType = null; // 启用写入分离后,数据库可能会主从同步,因此尝试从数据库获取迁移数据不作连接限制 var lastMigration = dbContextAccessor.Migrations .FirstOrDefaultByMax(s => s.CreatedTimeTicks); if (lastMigration.IsNotNull()) { var buffer = ModelSnapshotCompiler.RestoreAssembly(lastMigration.ModelBody); var modelAssembly = Assembly.Load(buffer); snapshotType = modelAssembly.GetType(lastMigration.ModelSnapshotName, throwOnError: true, ignoreCase: false); } if (snapshotType.IsNotNull()) { return snapshotType.EnsureCreate <ModelSnapshot>().Model; } return null; }); })); }
protected virtual void AddMigration (DataDbContextAccessor <TAudit, TAuditProperty, TMigration, TTabulation, TTenant, TGenId, TIncremId, TCreatedBy> dbContextAccessor) { if (!dbContextAccessor.IsWritingConnectionString()) { return; } (var body, var hash) = CreateModelSnapshot(dbContextAccessor, out var typeName); dbContextAccessor.MigrationsManager.TryAdd(p => p.ModelHash == hash, () => { var identifierGenerator = (IDataStoreIdentificationGenerator <TGenId>)dbContextAccessor .GetService <IStoreIdentificationGenerator>(); var migration = ObjectExtensions.EnsureCreate <TMigration>(); migration.Id = identifierGenerator.GenerateMigrationId(); migration.PopulateCreation(identifierGenerator.Clock); migration.AccessorName = dbContextAccessor.CurrentType.GetDisplayNameWithNamespace(); migration.ModelSnapshotName = typeName; migration.ModelBody = body; migration.ModelHash = hash; return(migration); }, addedPost => { if (!dbContextAccessor.RequiredSaveChanges) { dbContextAccessor.RequiredSaveChanges = true; } // 移除当前缓存 var cacheKey = DbContextAccessorHelper.GetMigrationCacheKey(dbContextAccessor); MemoryCache.Remove(cacheKey); // 发送迁移通知 var mediator = dbContextAccessor.GetService <IMediator>(); mediator.Publish(new MigrationNotification <TMigration> { Migration = addedPost.Entity }) .ConfigureAwaitCompleted(); }); }