Example #1
0
        /// <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;
                });
            }));
        }
Example #2
0
        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();
            });
        }
 private static FilePathCombiner GetReportFilePath(DbContextAccessorBase accessor)
 => DbContextAccessorHelper.GenerateAccessorFilePath(accessor,
                                                     ".txt", d => d.DatabasesReportDirectory);
Example #4
0
 private static string GetCacheKey(FilePathCombiner filePath)
 => DbContextAccessorHelper.GenerateAccessorKey(nameof(MigrationCommandExecutionValidator), filePath);
Example #5
0
 private static FilePathCombiner GetFilePathCombiner(DbContextAccessorBase accessor)
 => DbContextAccessorHelper.GenerateAccessorFilePath(accessor, ".json",
                                                     dependency => dependency.MigrationsConfigDirectory);