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();
}
}
}
SysConfig.cs
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; }
}
}
DbLog.cs
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에 따라 라이센스가 부여됩니다.