SQLite EF Core 데이터베이스 공급자 제한 사항
SQLite 공급자에는 여러 마이그레이션 제한 사항이 있습니다. 이러한 제한 사항의 대부분은 기본 SQLite 데이터베이스 엔진의 제한 사항의 결과이며 EF와 관련이 없습니다.
모델링 제한 사항
Entity Framework 관계형 데이터베이스 공급자가 공유하는 공통 관계형 라이브러리는 대부분의 관계형 데이터베이스 엔진에 공통적인 개념을 모델링하기 위한 API를 정의합니다. 이러한 개념 중 몇 가지는 SQLite 공급자에서 지원되지 않습니다.
- 스키마
- 시퀀스
- 데이터베이스에서 생성된 동시성 토큰(설명서 참조)
쿼리 제한 사항
SQLite는 기본적으로 다음 데이터 형식을 지원하지 않습니다. EF Core는 이러한 형식의 값을 읽고 쓸 수 있으며 같음(where e.Property == value
)에 대한 쿼리도 지원됩니다. 그러나 비교 및 순서 지정과 같은 다른 작업에는 클라이언트에 대한 평가가 필요합니다.
- DateTimeOffset
- 소수
- TimeSpan
- UInt64
DateTimeOffset
대신 DateTime 값을 사용하는 것이 좋습니다. 여러 표준 시간대를 처리할 때 값을 저장한 다음 적절한 표준 시간대로 다시 변환하기 전에 값을 UTC로 변환하는 것이 좋습니다.
Decimal
형식은 높은 수준의 정밀도를 제공합니다. 그러나 해당 수준의 정밀도가 필요하지 않은 경우 대신 double을 사용하는 것이 좋습니다. 값 변환기를 사용하여 클래스에서 10진수를 계속 사용할 수 있습니다.
modelBuilder.Entity<MyEntity>()
.Property(e => e.DecimalProperty)
.HasConversion<double>();
마이그레이션 제한 사항
SQLite 데이터베이스 엔진은 대부분의 다른 관계형 데이터베이스에서 지원하는 여러 스키마 작업을 지원하지 않습니다. 지원되지 않는 작업 중 하나를 SQLite 데이터베이스에 적용하려고 하면 NotSupportedException
이 throw됩니다.
특정 작업을 수행하기 위해 다시 빌드를 시도합니다. 다시 빌드는 EF Core 모델의 일부인 데이터베이스 아티팩트에서만 가능합니다. 데이터베이스 아티팩트가 모델의 일부가 아닌 경우(예: 마이그레이션 내에서 수동으로 만든 경우) NotSupportedException
dl 여전히 throw됩니다.
연산 | 지원? |
---|---|
AddCheckConstraint | ✔ (다시 빌드) |
AddColumn | ✔ |
AddForeignKey | ✔ (다시 빌드) |
AddPrimaryKey | ✔ (다시 빌드) |
AddUniqueConstraint | ✔ (다시 빌드) |
AlterColumn | ✔ (다시 빌드) |
CreateIndex | ✔ |
CreateTable | ✔ |
DropCheckConstraint | ✔ (다시 빌드) |
DropColumn | ✔ (다시 빌드) |
DropForeignKey | ✔ (다시 빌드) |
DropIndex | ✔ |
DropPrimaryKey | ✔ (다시 빌드) |
DropTable | ✔ |
DropUniqueConstraint | ✔ (다시 빌드) |
RenameColumn | ✔ |
RenameIndex | ✔ (다시 빌드) |
RenameTable | ✔ |
EnsureSchema | ✔ (no-op) |
DropSchema | ✔ (no-op) |
삽입 | ✔ |
업데이트 | ✔ |
삭제 | ✔ |
마이그레이션 제한 해결 방법
마이그레이션에서 코드를 수동으로 작성하여 다시 빌드를 수행하여 이러한 제한 사항 중 일부를 해결할 수 있습니다. 테이블 다시 작성에는 새 테이블 만들기, 새 테이블에 데이터 복사, 이전 테이블 삭제, 새 테이블 이름 바꾸기가 포함됩니다. 이러한 단계 중 일부를 수행하려면 Sql(string)
메서드를 사용해야 합니다.
자세한 내용은 SQLite 설명서에서 다른 종류의 테이블 스키마 변경 내용을 참조하세요.
Idempotent 스크립트 제한 사항
다른 데이터베이스와 달리 SQLite에는 절차 언어가 포함되지 않습니다. 이 때문에 멱등 마이그레이션 스크립트에 필요한 if-then 논리를 생성할 수 있는 방법은 없습니다.
데이터베이스에 적용된 마지막 마이그레이션을 알고 있는 경우 해당 마이그레이션에서 최신 마이그레이션으로 스크립트를 생성할 수 있습니다.
dotnet ef migrations script CurrentMigration
그렇지 않으면 dotnet ef database update
를 사용하여 마이그레이션을 적용하는 것이 좋습니다. 명령을 실행할 때 데이터베이스 파일을 지정할 수 있습니다.
dotnet ef database update --connection "Data Source=My.db"
동시 마이그레이션 보호
EF9는 마이그레이션을 실행할 때 잠금 메커니즘을 도입했습니다. 데이터베이스가 손상된 상태로 남을 수 있으므로 동시에 발생하는 여러 마이그레이션 실행으로부터 보호하는 것을 목표로 합니다. 이는 메서드를 사용하여 DbContext.Database.Migrate()
런타임에 마이그레이션을 적용하여 발생하는 잠재적인 문제 중 하나입니다(자세한 내용은 마이그레이션 적용 참조). 이를 완화하기 위해 EF는 마이그레이션 작업이 적용되기 전에 데이터베이스에 대한 배타적 잠금을 만듭니다.
아쉽게도 SQLite에는 기본 제공 잠금 메커니즘이 없으므로 EF는 별도의 테이블(__EFMigrationsLock
)을 만들고 잠금에 사용합니다. 마이그레이션이 완료되고 시드 코드 실행이 완료되면 잠금이 해제됩니다. 그러나 어떤 이유로 인해 복구할 수 없는 방식으로 마이그레이션이 실패하는 경우 잠금이 올바르게 해제되지 않을 수 있습니다. 이 경우 연속 마이그레이션이 SQL 실행에서 차단되므로 완료되지 않습니다. 데이터베이스에서 테이블을 삭제하여 수동으로 차단을 해제할 __EFMigrationsLock
수 있습니다.
참고 항목
.NET