[GitHub 액션] [코드 커버리지 보고서]
다음 패키지 중 하나를 사용하십시오.
버전 | 패키지 | 설명 |
---|---|---|
sqlite-net-pcl | .NET 표준 라이브러리 | |
sqlite-net-sqlcipher | 암호화 지원 포함 | |
sqlite-net-정적 | 플랫폼 제공 sqlite3에 P/Invoke를 사용하는 특수 버전 | |
sqlite-net-base | SQLitePCLRaw 번들이 없으므로 자신만의 공급자를 선택할 수 있습니다. |
SQLite-net은 .NET, .NET Core 및 Mono 애플리케이션이 SQLite 3 데이터베이스에 데이터를 저장할 수 있도록 하는 오픈 소스 최소 라이브러리입니다. 처음에는 Xamarin.iOS에서 작동하도록 설계되었지만 이후 모든 플랫폼(Xamarin.*, .NET, UWP, Azure 등)에서 작동하도록 성장했습니다.
SQLite-net은 빠르고 편리한 데이터베이스 계층으로 설계되었습니다. 그 디자인은 다음과 같은 목표를 따릅니다.
기존 프로젝트와 통합하기가 매우 쉽고 모든 .NET 플랫폼에서 실행됩니다.
빠르고 효율적인 SQLite 기반의 얇은 래퍼입니다. (이 라이브러리는 쿼리의 성능 병목 현상이 되어서는 안 됩니다.)
CRUD 작업 및 쿼리를 안전하게 실행하고(매개 변수 사용) 강력한 형식의 방식으로 쿼리 결과를 검색하는 매우 간단한 방법입니다.
클래스를 변경하지 않고도 데이터 모델을 사용하여 작업할 수 있습니다. (작은 반사 기반 ORM 레이어가 포함되어 있습니다.)
NuGet에서 sqlite-net-pcl을 설치합니다.
중요: .NET Standard 라이브러리 프로젝트 와 플랫폼 종속 앱 프로젝트 모두 에 NuGet 패키지를 추가해야 합니다.
SQLite-net은 모두 하나의 파일에 포함되어 있으며(알고 있어요, 정말 멋지죠?) 프로젝트에 쉽게 추가할 수 있습니다. 프로젝트에 SQLite.cs를 추가하기만 하면 테이블 생성을 시작할 준비가 된 것입니다. 비동기 구현은 SQLiteAsync.cs에서 찾을 수 있습니다.
이것은 이를 사용하는 사람들의 기여/제안/버그 보고를 환영하는 오픈 소스 프로젝트입니다. 라이브러리를 개선하는 방법에 대한 아이디어가 있으면 여기 GitHub에 문제를 게시하세요. 기여 방법을 확인해주세요.
에헴, 전체 문서를 보려면 Wiki를 참조하세요.
라이브러리에는 테이블 구성을 제어하는 데 사용할 수 있는 간단한 속성이 포함되어 있습니다. 간단한 주식 프로그램에서는 다음을 사용할 수 있습니다.
public class Stock
{
[ PrimaryKey , AutoIncrement ]
public int Id { get ; set ; }
public string Symbol { get ; set ; }
}
public class Valuation
{
[ PrimaryKey , AutoIncrement ]
public int Id { get ; set ; }
[ Indexed ]
public int StockId { get ; set ; }
public DateTime Time { get ; set ; }
public decimal Price { get ; set ; }
[ Ignore ]
public string IgnoreField { get ; set ; }
}
모델에서 개체를 정의한 후에는 API를 선택할 수 있습니다. 호출이 한 번에 하나씩 차단되는 "동기 API"를 사용하거나 호출이 차단되지 않는 "비동기 API"를 사용할 수 있습니다. 응답성을 높이기 위해 모바일 애플리케이션용 비동기 API를 사용하는 것이 좋습니다.
두 API 모두 아래 두 섹션에서 설명됩니다.
엔터티를 정의한 후에는 CreateTable
호출하여 데이터베이스에 테이블을 자동으로 생성할 수 있습니다.
// Get an absolute path to the database file
var databasePath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . MyDocuments ) , " MyData.db " ) ;
var db = new SQLiteConnection ( databasePath ) ;
db . CreateTable < Stock > ( ) ;
db . CreateTable < Valuation > ( ) ;
Insert
사용하여 데이터베이스에 행을 삽입할 수 있습니다. 테이블에 자동 증가 기본 키가 포함되어 있으면 삽입 후 해당 키의 값을 사용할 수 있습니다.
public static void AddStock ( SQLiteConnection db , string symbol ) {
var stock = new Stock ( ) {
Symbol = symbol
} ;
db . Insert ( stock ) ;
Console . WriteLine ( " {0} == {1} " , stock . Symbol , stock . Id ) ;
}
Update
및 Delete
에도 비슷한 방법이 있습니다.
데이터를 쿼리하는 가장 간단한 방법은 Table
메서드를 사용하는 것입니다. WHERE 절을 통해 제한하거나 ORDER BY 절을 추가하기 위한 조건자를 사용할 수 있습니다.
var query = db . Table < Stock > ( ) . Where ( v => v . Symbol . StartsWith ( " A " ) ) ;
foreach ( var stock in query )
Console . WriteLine ( " Stock: " + stock . Symbol ) ;
Query
메서드를 사용하여 하위 수준에서 데이터베이스를 쿼리할 수도 있습니다.
public static IEnumerable < Valuation > QueryValuations ( SQLiteConnection db , Stock stock ) {
return db . Query < Valuation > ( " select * from Valuation where StockId = ? " , stock . Id ) ;
}
Query
메서드에 대한 일반 매개 변수는 각 행에 대해 생성할 개체 유형을 지정합니다. 이는 테이블 클래스 중 하나일 수도 있고, 쿼리에서 반환된 열과 공용 속성이 일치하는 다른 클래스일 수도 있습니다. 예를 들어 위 쿼리를 다음과 같이 다시 작성할 수 있습니다.
public class Val
{
public decimal Money { get ; set ; }
public DateTime Date { get ; set ; }
}
public static IEnumerable < Val > QueryVals ( SQLiteConnection db , Stock stock ) {
return db . Query < Val > ( " select " Price " as " Money " , " Time " as " Date " from Valuation where StockId = ? " , stock . Id ) ;
}
Execute
메서드를 사용하여 데이터베이스의 낮은 수준 업데이트를 수행할 수 있습니다.
비동기 라이브러리는 TPL(작업 병렬 라이브러리)을 사용합니다. 따라서 Task
객체의 일반적인 사용과 async
및 await
키워드가 적합합니다.
엔터티를 정의한 후에는 CreateTableAsync
호출하여 자동으로 테이블을 생성할 수 있습니다.
// Get an absolute path to the database file
var databasePath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . MyDocuments ) , " MyData.db " ) ;
var db = new SQLiteAsyncConnection ( databasePath ) ;
await db . CreateTableAsync < Stock > ( ) ;
Console . WriteLine ( " Table created! " ) ;
Insert
사용하여 데이터베이스에 행을 삽입할 수 있습니다. 테이블에 자동 증가 기본 키가 포함되어 있으면 삽입 후 해당 키의 값을 사용할 수 있습니다.
var stock = new Stock ( )
{
Symbol = " AAPL "
} ;
await db . InsertAsync ( stock ) ;
Console . WriteLine ( " Auto stock id: {0} " , stock . Id ) ;
UpdateAsync
및 DeleteAsync
에도 비슷한 메서드가 있습니다.
데이터 쿼리는 Table
메서드를 사용하여 가장 간단하게 수행됩니다. 그러면 AsyncTableQuery
인스턴스가 다시 반환되며, WHERE 절을 통해 제한하거나 ORDER BY를 추가하기 위한 조건자를 추가할 수 있습니다. 특수 검색 방법 중 하나( ToListAsync
, FirstAsync
또는 FirstOrDefaultAsync
)가 호출될 때까지 데이터베이스는 물리적으로 접촉되지 않습니다.
var query = db . Table < Stock > ( ) . Where ( s => s . Symbol . StartsWith ( " A " ) ) ;
var result = await query . ToListAsync ( ) ;
foreach ( var s in result )
Console . WriteLine ( " Stock: " + s . Symbol ) ;
사용 가능한 저수준 방법에는 여러 가지가 있습니다. QueryAsync
메서드를 통해 직접 데이터베이스를 쿼리할 수도 있습니다. InsertAsync
등에서 제공하는 변경 작업 외에도 ExecuteAsync
메서드를 실행하여 데이터베이스 내에서 직접 데이터 집합을 변경할 수 있습니다.
또 다른 유용한 방법은 ExecuteScalarAsync
입니다. 이를 통해 데이터베이스에서 스칼라 값을 쉽게 반환할 수 있습니다.
var count = await db . ExecuteScalarAsync < int > ( " select count(*) from Stock " ) ;
Console . WriteLine ( string . Format ( " Found '{0}' stock items. " , count ) ) ;
sqlite-net은 일반적으로 CreateTable
및 Table
메서드를 사용하여 가벼운 ORM(object-relational-mapper)으로 사용됩니다. 그러나 쿼리를 수동으로 실행하는 편리한 방법으로 사용할 수도 있습니다.
다음은 테이블을 생성하고 테이블에 삽입하고(매개변수화된 명령을 사용하여) ORM 기능을 사용하지 않고 쿼리하는 예입니다.
db . Execute ( " create table Stock(Symbol varchar(100) not null) " ) ;
db . Execute ( " insert into Stock(Symbol) values (?) " , " MSFT " ) ;
var stocks = db . Query < Stock > ( " select * from Stock " ) ;
sqlite-net-sqlcipher NuGet 패키지를 사용하면 암호화된 데이터베이스를 사용할 수 있습니다.
데이터베이스 키는 연결 생성자에 전달된 SqliteConnectionString
에 설정됩니다.
var options = new SQLiteConnectionString ( databasePath , true ,
key : " password " ) ;
var encryptedDb = new SQLiteAsyncConnection ( options ) ;
암호화를 제어하기 위해 pragma를 설정해야 하는 경우 연결 문자열에 작업을 전달할 수 있습니다.
var options2 = new SQLiteConnectionString ( databasePath , true ,
key : " password " ,
preKeyAction : db => db . Execute ( " PRAGMA cipher_default_use_hmac = OFF; " ) ,
postKeyAction : db => db . Execute ( " PRAGMA kdf_iter = 128000; " ) ) ;
var encryptedDb2 = new SQLiteAsyncConnection ( options2 ) ;
이 프로젝트를 수용해 준 .NET 커뮤니티에 감사하고, 이 프로젝트를 훌륭하게 만드는 데 도움을 준 모든 기여자에게 감사드립니다.
훌륭한 로고를 제공해 주신 Tirza van Dijk(@tirzavdijk)에게도 감사드립니다!