c\#FreeSql 생산 환경 사용 시 백업 데이터베이스 자동 업그레이드
FreeSql 을 사용 하면 모든 ORM 데이터 베 이 스 를 포함 하 는 문제 가 발생 합 니 다.codefirst 모드 에서 코드 에 따라 데이터 베 이 스 를 자동 으로 업데이트 할 때 생산 환경 에서 사용 하지 않 는 것 을 권장 합 니 다.왜 일 까요?
사실은 사용 을 권장 하지 않 습 니 다.주로 코드 에 따라 데 이 터 를 자동 으로 생 성 할 때 데이터 의 손실 을 초래 할 수 있 습 니 다.예 를 들 어 필드 유형 을 수정 하고 자동 으로 업데이트 하 는 결 과 는 자신 이 생각 하 는 것 이 아 닐 수도 있 습 니 다.
그러나 일부 사용 장면 은 생산 환경 에서 자동 으로 업그레이드 해 야 한다.예 를 들 어
저 희 는 CS 클 라 이언 트 의 제품 이 있 습 니 다.고객 은 로 컬 오프라인 으로 사용 하고 고객 의 로 컬 배치,데이터 베이스 도 로 컬 데이터 베이스 입 니 다.버 전 은 1000 에서 1100 으로 교체 되 었 고 중간 에 100 개의 버 전 을 발 표 했 습 니 다.이 중간 에 데이터베이스 가 여러 번 변 경 될 수 있 습 니 다.우리 의 고객 도 전국 각지 에 널리 퍼 져 있 을 수 있 고 버 전도 모두 다르다.고객 이 새로운 수요 가 없 으 면 현재 의 오래된 버 전 을 계속 사용 할 수 있 습 니 다.새로운 수요 가 있 거나 새로운 기능 을 사용 하고 싶 을 때 만 버 전 을 업그레이드 할 수 있 습 니 다.그래서 업그레이드 시간 도 확실 하지 않다.업 그 레이 드 는 고객 에 게 새 소프트웨어 를 설치 하고 실행 한 후에 자동 으로 업 그 레이 드 를 해 야 한다.
그럼 정말 생산 환경 에서 사용 할 수 없 는 건 가요?
해결 방안:
개요 설명:
해결 의 방향 은 바로 자동 업그레이드 이지 만 업그레이드 가 필요 하 다 고 판단 할 때 자동 으로 업그레이드 되 고 업그레이드 하기 전에 데이터 베 이 스 를 백업 하 는 것 이다.
구체 적 절차
프로그램 내 에 데이터베이스 변경 이 있 을 때마다 버 전 을 발표 할 때 프로그램 내 대응 하 는 버 전 을 수정 합 니 다.예 를 들 어 처음에는 1000,최신 은 1100.
데이터베이스 에 SysConfig 표를 추가 합 니 다.필드 에 DbVer 를 포함 하여 현재 데이터베이스 버 전 번 호 를 표시 합 니 다.
데이터베이스 에 DbLog 표를 추가 하고 데이터베이스 업그레이드 로 그 를 기록 합 니 다.이 옵션 을 선택 할 수 있 습 니 다.
처음 설치 할 때 데이터베이스 파일 이 존재 하지 않 는 지 확인 하고 처음 설치 할 때 SysConfig 표 와 DbLog 표를 만 들 고 SysConfig 표 DbVer 를 프로그램 에 기 록 된 버 전 번호 로 업데이트 합 니 다.DbLog 테이블 로그 추가
나중에 다시 실행 할 때 SysConfig 표 DbVer 를 가 져 와 프로그램 과 일치 하 는 지 판단 합 니 다.
만약 데이터베이스 가 프로그램 보다 크다 면,낮은 버 전의 프로그램 을 실행 하 는 것 을 설명 하고,상황 에 따라 실행 을 금지 할 수 있다.데이터 베 이 스 를 동기 화하 지 않 고 계속 실행 할 수도 있 고 실제 상황 에 따라 결정 할 수도 있다.프로그램 과 데이터베이스 의 일치 성에 대한 요구 가 높 으 면 실행 을 금지 할 수 있다.
만약 데이터베이스 가 프로그램 보다 작다 면 데이터 베 이 스 를 업그레이드 해 야 한 다 는 것 을 설명 합 니 다.이때 기 존 데이터 베 이 스 를 백업 한 다음 동기 화 데이터 베 이 스 를 실행 합 니 다.
상세 설명:
코드 를 직접 올 리 는 것 은 무엇 보다 잘 알 고 있다.
program.cs 파일 코드
using Bonn.Helper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using FreeSql.DataAnnotations;
using WindowsClient.Model;
using System.Reflection;
namespace WindowsClient
{
    static class Program
    {
        /// <summary>
        ///        
        /// </summary>
        private static string CustDbPath = Application.StartupPath + $"\\   \\cust.db";
        /// <summary>
        ///    ORM
        /// </summary>
        public static IFreeSql fsql;
        /// <summary>
        ///         
        /// </summary>
        private static int ServerDbVer = 1000;
        /// <summary>
        ///          。
        /// </summary>
        [STAThread]
        static void Main()
        {
            try
            {
                //       ,        ,   freesql      ,              
                var custDbPathExists = File.Exists(CustDbPath);
                //deebug            ,release    
                bool syncDbStructure = false;
#if DEBUG
                syncDbStructure = true;
#endif
                fsql = new FreeSql.FreeSqlBuilder()
                    .UseConnectionString(FreeSql.DataType.Sqlite, $@"Data Source={CustDbPath}; Pooling=true;Min Pool Size=1")
                    .UseAutoSyncStructure(syncDbStructure) //deebug            ,release    
                    .UseMonitorCommand(cmd => Console.WriteLine($"  :{cmd.CommandText}\r
"))
                    .Build(); //       Singleton     
                if(syncDbStructure)
                {
                    //         ,          ,     ,           
                    fsql.CodeFirst.SyncStructure(GetTypesByTableAttribute());
                }
                if (custDbPathExists == false)
                {
                    //        ,       
                    fsql.CodeFirst.SyncStructure(GetTypesByTableAttribute());
                    var sysConfig = new SysConfig();
                    sysConfig.DbVer = ServerDbVer;
                    var dbResult = fsql.Insert(sysConfig).ExecuteAffrows();
                    if (dbResult <= 0)
                        throw new Exception("       。");
                    var row = new DbLog();
                    row.DbVer = ServerDbVer;
                    fsql.Insert(row).ExecuteAffrows();
                }
                int localDbVer = fsql.Select<SysConfig>().First().DbVer;
                if (localDbVer != ServerDbVer)
                {
                    //        ,    
                    //     
                    File.Copy(CustDbPath, Application.StartupPath + $"\\   \\cust{DateTime.Now:yyyyMMddHHmmss}.db");
                    //     
                    fsql.CodeFirst.SyncStructure(GetTypesByTableAttribute());
                    var row = new DbLog();
                    row.DbVer = ServerDbVer;
                    fsql.Insert(row).ExecuteAffrows();
                }
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FrmMain());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "   ", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        public static Type[] GetTypesByTableAttribute()
        {
            List<Type> tableAssembies = new List<Type>();
            foreach (Type type in Assembly.GetAssembly(typeof(IEntity)).GetExportedTypes())
            {
                foreach (Attribute attribute in type.GetCustomAttributes())
                {
                    if (attribute is TableAttribute tableAttribute)
                    {
                        if (tableAttribute.DisableSyncStructure == false)
                        {
                            tableAssembies.Add(type);
                        }
                    }
                }
            };
            return tableAssembies.ToArray();
        }
    }
}
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsClient.Model
{
    /// <summary>
    /// 
    /// </summary>
    [Table(Name = "sys_config")]
    public class SysConfig : IEntity
    {
        /// <summary>
        ///   
        /// </summary>
        [Column(Name = "id", IsIdentity = true, IsPrimary = true)]
        public int Id { get; set; }
        /// <summary>
        ///   
        /// </summary>
        [Column(Name = "dbVer")]
        public int DbVer { get; set; }
        /// <summary>
        ///     
        /// </summary>
        [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)]
        public DateTime CreateTime { get; set; }
        /// <summary>
        ///     
        /// </summary>
        [Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
        public DateTime UpdateTime { get; set; }
    }
}
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsClient.Model
{
    /// <summary>
    /// 
    /// </summary>
    [Table(Name = "db_log")]
    public class DbLog : IEntity
    {
        /// <summary>
        ///   
        /// </summary>
        [Column(Name = "id", IsIdentity = true, IsPrimary = true)]
        public int Id { get; set; }
        /// <summary>
        ///   
        /// </summary>
        [Column(Name = "dbVer")]
        public int DbVer { get; set; }
        /// <summary>
        ///     
        /// </summary>
        [Column(ServerTime = DateTimeKind.Local, CanUpdate = false)]
        public DateTime CreateTime { get; set; }
        /// <summary>
        ///     
        /// </summary>
        [Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
        public DateTime UpdateTime { get; set; }
    }
}예전 에는 손 으로 쓴 SQL 문 구 였 는데 지금 은 FreeSql 을 사용 하 는 것 이 훨씬 편리 해 졌 다.
이상 은 c\#FreeSql 생산 환경 을 사용 하여 백업 데이터 베 이 스 를 자동 으로 업그레이드 하 는 상세 한 내용 입 니 다.c\#FreeSql 로 백업 데이터 베 이 스 를 자동 으로 업그레이드 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.