다음을 통해 공유


로컬 SQLite.NET 데이터베이스에 데이터 저장

이 빠른 시작에서 다음과 같은 작업을 수행하는 방법을 알아봅니다.

  • 데이터를 SQLite.NET 데이터베이스에 로컬로 저장합니다.

이 빠른 시작은 Xamarin.Forms Shell 애플리케이션에서 로컬 SQLite.NET 데이터베이스에 데이터를 저장하는 방법을 안내합니다. 최종 애플리케이션은 다음과 같습니다.

Notes 페이지Note Entry 페이지

필수 조건

이 빠른 시작을 시도하기 전에 이전 빠른 시작을 성공적으로 완료해야 합니다.

Visual Studio를 사용하여 앱 업데이트

  1. Visual Studio를 시작하고 Notes 솔루션을 엽니다.

  2. 솔루션 탐색기에서 Notes 솔루션을 마우스 오른쪽 단추로 클릭하고 솔루션에 대한 NuGet 패키지 관리...를 선택합니다.

    NuGet 패키지 관리

  3. NuGet 패키지 관리자에서 찾아보기 탭을 선택하고 sqlite-net-pcl NuGet 패키지를 검색합니다.

    Warning

    이름이 유사한 NuGet 패키지가 많이 있습니다. 올바른 패키지에는 이러한 특성이 있습니다.

    패키지 이름에도 불구하고 이 NuGet 패키지는 .NET 표준 패키지에서 사용할 수 있습니다.

    NuGet 패키지 관리자에서 올바른 sqlite-net-pcl 패키지를 선택하고 프로젝트 확인란을 선택한 다음 설치 단추를 클릭하여 솔루션에 추가합니다.

    sqlite-net-pcl 선택

    이 패키지는 데이터베이스 작업을 애플리케이션에 통합하는 데 사용되며, 솔루션의 모든 프로젝트에 추가됩니다.

    Important

    SQLite.NET praeclarum/sqlite-net 리포지토리에서 지원되는 타사 라이브러리입니다.

    NuGet 패키지 관리자를 닫습니다.

  4. 솔루션 탐색기Notes 프로젝트에 있는 Models 폴더에서 Note.cs를 열고 기존 코드를 다음 코드로 바꿉니다.

    using System;
    using SQLite;
    
    namespace Notes.Models
    {
        public class Note
        {
            [PrimaryKey, AutoIncrement]
            public int ID { get; set; }
            public string Text { get; set; }
            public DateTime Date { get; set; }
        }
    }
    

    이 클래스는 애플리케이션의 각 노트에 대한 데이터를 저장하는 Note 모델을 정의합니다. ID 속성은 SQLite.NET 데이터베이스의 각 Note 인스턴스가 SQLite.NET에서 제공되는 고유 ID를 갖도록 PrimaryKeyAutoIncrement 특성과 함께 표시됩니다.

    CTRL+S를 눌러 변경 내용을 Note.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  5. 솔루션 탐색기에서 Data라는 새 폴더를 Notes 프로젝트에 추가합니다.

  6. 솔루션 탐색기Notes 프로젝트에서 Data 폴더에 NoteDatabase라는 새 클래스를 추가합니다.

  7. NoteDatabase.cs에서 기존 코드를 다음 코드로 바꿉니다.

    using System.Collections.Generic;
    using System.Threading.Tasks;
    using SQLite;
    using Notes.Models;
    
    namespace Notes.Data
    {
        public class NoteDatabase
        {
            readonly SQLiteAsyncConnection database;
    
            public NoteDatabase(string dbPath)
            {
                database = new SQLiteAsyncConnection(dbPath);
                database.CreateTableAsync<Note>().Wait();
            }
    
            public Task<List<Note>> GetNotesAsync()
            {
                //Get all notes.
                return database.Table<Note>().ToListAsync();
            }
    
            public Task<Note> GetNoteAsync(int id)
            {
                // Get a specific note.
                return database.Table<Note>()
                                .Where(i => i.ID == id)
                                .FirstOrDefaultAsync();
            }
    
            public Task<int> SaveNoteAsync(Note note)
            {
                if (note.ID != 0)
                {
                    // Update an existing note.
                    return database.UpdateAsync(note);
                }
                else
                {
                    // Save a new note.
                    return database.InsertAsync(note);
                }
            }
    
            public Task<int> DeleteNoteAsync(Note note)
            {
                // Delete a note.
                return database.DeleteAsync(note);
            }
        }
    }
    

    이 클래스에는 데이터베이스를 만들고, 그 데이터베이스로부터 데이터를 읽고 쓰는 코드가 있습니다. 코드는 데이터베이스 작업을 백그라운드 스레드로 이동시키는 비동기 SQLite.NET API를 사용합니다. 또한 NoteDatabase 생성자는 데이터베이스 파일의 경로를 인수로 사용합니다. 이 경로는 다음 단계에서 App 클래스에 의해 제공됩니다.

    CTRL+S를 눌러 변경 내용을 NoteDatabase.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  8. 솔루션 탐색기Notes 프로젝트에서 App.xaml을 확장하고 App.xaml.cs를 두 번 클릭하여 엽니다. 그런 다음 기존 코드를 다음 코드로 바꿉니다.

    using System;
    using System.IO;
    using Notes.Data;
    using Xamarin.Forms;
    
    namespace Notes
    {
        public partial class App : Application
        {
            static NoteDatabase database;
    
            // Create the database connection as a singleton.
            public static NoteDatabase Database
            {
                get
                {
                    if (database == null)
                    {
                        database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3"));
                    }
                    return database;
                }
            }
    
            public App()
            {
                InitializeComponent();
                MainPage = new AppShell();
            }
    
            protected override void OnStart()
            {
            }
    
            protected override void OnSleep()
            {
            }
    
            protected override void OnResume()
            {
            }
        }
    }
    

    이 코드는 새 NoteDatabase 인스턴스를 singleton으로 만들고 데이터베이스의 파일 이름을 NoteDatabase 생성자에 인수로 전달하는 Database 속성을 정의합니다. 데이터베이스를 싱글톤으로 노출하면 애플리케이션이 실행되는 동안 열린 상태로 유지되는 단일 데이터베이스 연결이 생성되므로 데이터베이스 작업이 수행될 때마다 데이터베이스 파일을 열거나 닫는 비용을 피할 수 있는 이점이 있습니다.

    CTRL+S를 눌러 변경 내용을 App.xaml.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  9. 솔루션 탐색기Notes 프로젝트에서 Views 폴더에 있는 NotesPage.xaml을 확장하고 NotesPage.xaml.cs를 엽니다. 그런 다음 OnAppearingOnSelectionChanged 메서드를 다음 코드로 바꿉니다.

    protected override async void OnAppearing()
    {
        base.OnAppearing();
    
        // Retrieve all the notes from the database, and set them as the
        // data source for the CollectionView.
        collectionView.ItemsSource = await App.Database.GetNotesAsync();
    }
    
    async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.CurrentSelection != null)
        {
            // Navigate to the NoteEntryPage, passing the ID as a query parameter.
            Note note = (Note)e.CurrentSelection.FirstOrDefault();
            await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
        }
    }    
    

    OnAppearing 메서드는 CollectionView를 데이터베이스에 저장된 노트로 채웁니다. OnSelectionChanged메서드는 NoteEntryPage로 이동하여 선택한 Note 개체의 ID 속성을 쿼리 매개 변수로 전달합니다.

    CTRL+S를 눌러 변경 내용을 NotesPage.xaml.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  10. 솔루션 탐색기에서 Views 폴더에 있는 NoteEntryPage.xaml을 확장하고 NoteEntryPage.xaml.cs를 엽니다. 그런 다음 LoadNote, OnSaveButtonClicked, OnDeleteButtonClicked 메서드를 다음 코드로 바꿉니다.

    async void LoadNote(string itemId)
    {
        try
        {
            int id = Convert.ToInt32(itemId);
            // Retrieve the note and set it as the BindingContext of the page.
            Note note = await App.Database.GetNoteAsync(id);
            BindingContext = note;
        }
        catch (Exception)
        {
            Console.WriteLine("Failed to load note.");
        }
    }
    
    async void OnSaveButtonClicked(object sender, EventArgs e)
    {
        var note = (Note)BindingContext;
        note.Date = DateTime.UtcNow;
        if (!string.IsNullOrWhiteSpace(note.Text))
        {
            await App.Database.SaveNoteAsync(note);
        }
    
        // Navigate backwards
        await Shell.Current.GoToAsync("..");
    }
    
    async void OnDeleteButtonClicked(object sender, EventArgs e)
    {
        var note = (Note)BindingContext;
        await App.Database.DeleteNoteAsync(note);
    
        // Navigate backwards
        await Shell.Current.GoToAsync("..");
    }
    

    NoteEntryPageLoadNote 메서드를 사용하여 ID가 페이지에 쿼리 매개 변수로 전달된 노트를 데이터베이스에서 검색하고, 페이지의 BindingContextNote 개체로 저장합니다. OnSaveButtonClicked 이벤트 처리기가 실행되면 Note 인스턴스가 데이터베이스에 저장되고 애플리케이션이 이전 페이지로 다시 이동합니다. OnDeleteButtonClicked 이벤트 처리기가 실행되면 Note 인스턴스가 데이터베이스에서 삭제되고 애플리케이션이 이전 페이지로 다시 이동합니다.

    CTRL+S를 눌러 변경 내용을 NoteEntryPage.xaml.cs에 저장합니다.

  11. 각 플랫폼에서 프로젝트를 빌드하고 실행합니다. 자세한 내용은 빠른 시작 빌드를 참조하세요.

    NotesPage에서 추가 단추를 눌러 NoteEntryPage로 이동하고 노트를 입력합니다. 노트를 저장한 후 애플리케이션은 NotesPage로 다시 이동합니다.

    다양한 길이의 여러 노트를 입력하여 애플리케이션 동작을 관찰합니다. 애플리케이션을 닫고 다시 시작하여 입력한 노트가 데이터베이스에 저장되었는지 확인합니다.

Mac용 Visual Studio를 사용하여 앱 업데이트

  1. Mac용 Visual Studio를 시작하고 Notes 솔루션을 엽니다.

  2. Solution Pad에서 Notes 솔루션을 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리...를 선택합니다.

    NuGet 패키지 관리

  3. NuGet 패키지 관리에서 찾아보기 탭을 선택하고, sqlite-net-pcl NuGet 패키지를 검색합니다.

    Warning

    이름이 유사한 NuGet 패키지가 많이 있습니다. 올바른 패키지에는 이러한 특성이 있습니다.

    패키지 이름에도 불구하고 이 NuGet 패키지는 .NET 표준 패키지에서 사용할 수 있습니다.

    NuGet 패키지 관리 대화 상자에서 sqlite-net-pcl 패키지를 선택하고 패키지 추가 단추를 클릭하여 솔루션에 추가합니다.

    sqlite-net-pcl 선택

    이 패키지는 데이터베이스 작업을 애플리케이션에 통합하는 데 사용됩니다.

  4. 프로젝트 선택 대화 상자에서 모든 확인란이 선택되어 있는지 확인하고 확인 단추를 누릅니다.

    모든 프로젝트에 패키지 추가

    이렇게 하면 솔루션의 모든 프로젝트에 NuGet 패키지가 추가됩니다.

  5. Solution PadNotes 프로젝트에서 Models 폴더의 Note.cs를 열고 기존 코드를 다음 코드로 바꿉니다.

    using System;
    using SQLite;
    
    namespace Notes.Models
    {
        public class Note
        {
            [PrimaryKey, AutoIncrement]
            public int ID { get; set; }
            public string Text { get; set; }
            public DateTime Date { get; set; }
        }
    }
    

    이 클래스는 애플리케이션의 각 노트에 대한 데이터를 저장하는 Note 모델을 정의합니다. ID 속성은 SQLite.NET 데이터베이스의 각 Note 인스턴스가 SQLite.NET에서 제공되는 고유 ID를 갖도록 PrimaryKeyAutoIncrement 특성과 함께 표시됩니다.

    파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 Note.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  6. Solution Pad에서 Data라는 새 폴더를 Notes 프로젝트에 추가합니다.

  7. Solution PadNotes 프로젝트에서 Data 폴더에 NoteDatabase라는 새 클래스를 추가합니다.

  8. NoteDatabase.cs에서 기존 코드를 다음 코드로 바꿉니다.

    using System.Collections.Generic;
    using System.Threading.Tasks;
    using SQLite;
    using Notes.Models;
    
    namespace Notes.Data
    {
        public class NoteDatabase
        {
            readonly SQLiteAsyncConnection database;
    
            public NoteDatabase(string dbPath)
            {
                database = new SQLiteAsyncConnection(dbPath);
                database.CreateTableAsync<Note>().Wait();
            }
    
            public Task<List<Note>> GetNotesAsync()
            {
                //Get all notes.
                return database.Table<Note>().ToListAsync();
            }
    
            public Task<Note> GetNoteAsync(int id)
            {
                // Get a specific note.
                return database.Table<Note>()
                                .Where(i => i.ID == id)
                                .FirstOrDefaultAsync();
            }
    
            public Task<int> SaveNoteAsync(Note note)
            {
                if (note.ID != 0)
                {
                    // Update an existing note.
                    return database.UpdateAsync(note);
                }
                else
                {
                    // Save a new note.
                    return database.InsertAsync(note);
                }
            }
    
            public Task<int> DeleteNoteAsync(Note note)
            {
                // Delete a note.
                return database.DeleteAsync(note);
            }
        }
    }
    

    이 클래스에는 데이터베이스를 만들고, 그 데이터베이스로부터 데이터를 읽고 쓰는 코드가 있습니다. 코드는 데이터베이스 작업을 백그라운드 스레드로 이동시키는 비동기 SQLite.NET API를 사용합니다. 또한 NoteDatabase 생성자는 데이터베이스 파일의 경로를 인수로 사용합니다. 이 경로는 다음 단계에서 App 클래스에 의해 제공됩니다.

    파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NoteDatabase.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  9. Solution PadNotes 프로젝트에서 App.xaml을 확장하고 App.xaml.cs를 두 번 클릭하여 엽니다. 그런 다음 기존 코드를 다음 코드로 바꿉니다.

    using System;
    using System.IO;
    using Notes.Data;
    using Xamarin.Forms;
    
    namespace Notes
    {
        public partial class App : Application
        {
            static NoteDatabase database;
    
            // Create the database connection as a singleton.
            public static NoteDatabase Database
            {
                get
                {
                    if (database == null)
                    {
                        database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3"));
                    }
                    return database;
                }
            }
    
            public App()
            {
                InitializeComponent();
                MainPage = new AppShell();
            }
    
            protected override void OnStart()
            {
            }
    
            protected override void OnSleep()
            {
            }
    
            protected override void OnResume()
            {
            }
        }
    }
    

    이 코드는 새 NoteDatabase 인스턴스를 singleton으로 만들고 데이터베이스의 파일 이름을 NoteDatabase 생성자에 인수로 전달하는 Database 속성을 정의합니다. 데이터베이스를 싱글톤으로 노출하면 애플리케이션이 실행되는 동안 열린 상태로 유지되는 단일 데이터베이스 연결이 생성되므로 데이터베이스 작업이 수행될 때마다 데이터베이스 파일을 열거나 닫는 비용을 피할 수 있는 이점이 있습니다.

    파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 App.xaml.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  10. Solution PadNotes 프로젝트에서 Views 폴더에 있는 NotesPage.xaml을 확장하고 NotesPage.xaml.cs를 엽니다. 그런 다음 OnAppearingOnSelectionChanged 메서드를 다음 코드로 바꿉니다.

    protected override async void OnAppearing()
    {
        base.OnAppearing();
    
        // Retrieve all the notes from the database, and set them as the
        // data source for the CollectionView.
        collectionView.ItemsSource = await App.Database.GetNotesAsync();
    }
    
    async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.CurrentSelection != null)
        {
            // Navigate to the NoteEntryPage, passing the ID as a query parameter.
            Note note = (Note)e.CurrentSelection.FirstOrDefault();
            await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
        }
    }    
    

    OnAppearing 메서드는 CollectionView를 데이터베이스에 저장된 노트로 채웁니다. OnSelectionChanged메서드는 NoteEntryPage로 이동하여 선택한 Note 개체의 ID 속성을 쿼리 매개 변수로 전달합니다.

    파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NotesPage.xaml.cs에 저장합니다.

    Warning

    다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.

  11. Solution Pad에서 Views 폴더에 있는 NoteEntryPage.xaml을 확장하고 NoteEntryPage.xaml.cs를 엽니다. 그런 다음 LoadNote, OnSaveButtonClicked, OnDeleteButtonClicked 메서드를 다음 코드로 바꿉니다.

    async void LoadNote(string itemId)
    {
        try
        {
            int id = Convert.ToInt32(itemId);
            // Retrieve the note and set it as the BindingContext of the page.
            Note note = await App.Database.GetNoteAsync(id);
            BindingContext = note;
        }
        catch (Exception)
        {
            Console.WriteLine("Failed to load note.");
        }
    }
    
    async void OnSaveButtonClicked(object sender, EventArgs e)
    {
        var note = (Note)BindingContext;
        note.Date = DateTime.UtcNow;
        if (!string.IsNullOrWhiteSpace(note.Text))
        {
            await App.Database.SaveNoteAsync(note);
        }
    
        // Navigate backwards
        await Shell.Current.GoToAsync("..");
    }
    
    async void OnDeleteButtonClicked(object sender, EventArgs e)
    {
        var note = (Note)BindingContext;
        await App.Database.DeleteNoteAsync(note);
    
        // Navigate backwards
        await Shell.Current.GoToAsync("..");
    }
    

    NoteEntryPageLoadNote 메서드를 사용하여 ID가 페이지에 쿼리 매개 변수로 전달된 노트를 데이터베이스에서 검색하고, 페이지의 BindingContextNote 개체로 저장합니다. OnSaveButtonClicked 이벤트 처리기가 실행되면 Note 인스턴스가 데이터베이스에 저장되고 애플리케이션이 이전 페이지로 다시 이동합니다. OnDeleteButtonClicked 이벤트 처리기가 실행되면 Note 인스턴스가 데이터베이스에서 삭제되고 애플리케이션이 이전 페이지로 다시 이동합니다.

    파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NoteEntryPage.xaml.cs에 저장합니다.

  12. 각 플랫폼에서 프로젝트를 빌드하고 실행합니다. 자세한 내용은 빠른 시작 빌드를 참조하세요.

    NotesPage에서 추가 단추를 눌러 NoteEntryPage로 이동하고 노트를 입력합니다. 노트를 저장한 후 애플리케이션은 NotesPage로 다시 이동합니다.

    다양한 길이의 여러 노트를 입력하여 애플리케이션 동작을 관찰합니다. 애플리케이션을 닫고 다시 시작하여 입력한 노트가 데이터베이스에 저장되었는지 확인합니다.

다음 단계

이 빠른 시작에서는 다음과 같은 방법을 배웠습니다.

  • 데이터를 SQLite.NET 데이터베이스에 로컬로 저장합니다.

XAML 스타일을 사용하여 애플리케이션의 스타일을 지정하려면 다음 빠른 시작으로 진행합니다.