Udostępnij za pomocą


Używanie ADO.NET z platformą Xamarin.iOS

Platforma Xamarin ma wbudowaną obsługę bazy danych SQLite, która jest dostępna w systemie iOS, uwidoczniona przy użyciu znanego rozwiązania ADO. Składnia przypominająca platformę NET. Korzystanie z tych interfejsów API wymaga pisania instrukcji SQL przetwarzanych przez bibliotekę SQLite, takich jak CREATE TABLE, INSERT i SELECT instrukcji.

Odwołania do zestawów

Aby uzyskać dostęp do sqLite za pośrednictwem ADO.NET, należy dodać System.Data odwołania do Mono.Data.Sqlite projektu systemu iOS, jak pokazano tutaj (w przypadku przykładów w Visual Studio dla komputerów Mac i Visual Studio):

Kliknij prawym przyciskiem myszy pozycję Odwołania > edytuj odwołania... a następnie kliknij, aby wybrać wymagane zestawy.

Informacje o pliku Mono.Data.Sqlite

Użyjemy Mono.Data.Sqlite.SqliteConnection klasy , aby utworzyć pusty plik bazy danych, a następnie utworzyć wystąpienie SqliteCommand obiektów, których możemy użyć do wykonywania instrukcji SQL względem bazy danych.

  1. Tworzenie pustej bazy danych — wywołaj CreateFile metodę z prawidłową (tj. zapisywalną) ścieżką pliku. Przed wywołaniem tej metody należy sprawdzić, czy plik już istnieje. W przeciwnym razie zostanie utworzona nowa (pusta) baza danych w górnej części starego pliku, a dane w starym pliku zostaną utracone:

    Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);

    Uwaga

    Zmienna dbPath powinna być określana zgodnie z regułami omówionymi wcześniej w tym dokumencie.

  2. Tworzenie Połączenie bazy danych — po utworzeniu pliku bazy danych SQLite można utworzyć obiekt połączenia w celu uzyskania dostępu do danych. Połączenie jest konstruowane przy użyciu parametry połączenia, który ma formę Data Source=file_path, jak pokazano poniżej:

    var connection = new SqliteConnection ("Data Source=" + dbPath);
    connection.Open();
    // do stuff
    connection.Close();
    

    Jak wspomniano wcześniej, połączenie nigdy nie powinno być ponownie używane w różnych wątkach. Jeśli masz wątpliwości, utwórz połączenie zgodnie z potrzebami i zamknij je po zakończeniu; ale należy pamiętać o robieniu tego częściej niż jest to wymagane.

  3. Tworzenie i wykonywanie polecenia bazy danych — po nawiązaniu połączenia możemy wykonać na nim dowolne polecenia SQL. Poniższy kod przedstawia wykonywaną instrukcję CREATE TABLE.

    using (var command = connection.CreateCommand ()) {
        command.CommandText = "CREATE TABLE [Items] ([_id] int, [Symbol] ntext, [Name] ntext);";
        var rowcount = command.ExecuteNonQuery ();
    }
    

Podczas wykonywania kodu SQL bezpośrednio w bazie danych należy podjąć normalne środki ostrożności, aby nie wysyłać nieprawidłowych żądań, takich jak próba utworzenia tabeli, która już istnieje. Śledź strukturę bazy danych, aby nie powodować błędu SqliteException, takiego jak "Tabela błędów SQLite [Items] już istnieje".

Podstawowy dostęp do danych

Przykładowy kod DataAccess_Basic dla tego dokumentu wygląda następująco podczas uruchamiania w systemie iOS:

iOS ADO.NET sample

Poniższy kod ilustruje sposób wykonywania prostych operacji SQLite i przedstawia wyniki w postaci tekstu w oknie głównym aplikacji.

Należy uwzględnić następujące przestrzenie nazw:

using System;
using System.IO;
using Mono.Data.Sqlite;

Poniższy przykładowy kod przedstawia całą interakcję z bazą danych:

  1. Tworzenie pliku bazy danych
  2. Wstawianie niektórych danych
  3. Wykonywanie zapytań dotyczących danych

Te operacje zwykle pojawiają się w wielu miejscach w całym kodzie, na przykład można utworzyć plik bazy danych i tabele, gdy aplikacja po raz pierwszy uruchamia i wykonuje odczyty i zapisy danych na poszczególnych ekranach w aplikacji. W poniższym przykładzie pogrupowano je w jedną metodę dla tego przykładu:

public static SqliteConnection connection;
public static string DoSomeDataAccess ()
{
    // determine the path for the database file
    string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "adodemo.db3");

    bool exists = File.Exists (dbPath);

    if (!exists) {
        Console.WriteLine("Creating database");
        // Need to create the database before seeding it with some data
        Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);
        connection = new SqliteConnection ("Data Source=" + dbPath);

        var commands = new[] {
            "CREATE TABLE [Items] (_id ntext, Symbol ntext);",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'AAPL')",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('2', 'GOOG')",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('3', 'MSFT')"
        };
        // Open the database connection and create table with data
        connection.Open ();
        foreach (var command in commands) {
            using (var c = connection.CreateCommand ()) {
                c.CommandText = command;
                var rowcount = c.ExecuteNonQuery ();
                Console.WriteLine("\tExecuted " + command);
            }
        }
    } else {
        Console.WriteLine("Database already exists");
        // Open connection to existing database file
        connection = new SqliteConnection ("Data Source=" + dbPath);
        connection.Open ();
    }

    // query the database to prove data was inserted!
    using (var contents = connection.CreateCommand ()) {
        contents.CommandText = "SELECT [_id], [Symbol] from [Items]";
        var r = contents.ExecuteReader ();
        Console.WriteLine("Reading data");
        while (r.Read ())
            Console.WriteLine("\tKey={0}; Value={1}",
                              r ["_id"].ToString (),
                              r ["Symbol"].ToString ());
    }
    connection.Close ();
}

Bardziej złożone zapytania

Ponieważ sqLite umożliwia uruchamianie dowolnych poleceń SQL względem danych, można wykonać dowolne instrukcje CREATE, INSERT, UPDATE, DELETE lub SELECT. Informacje o poleceniach SQL obsługiwanych przez sqLite można przeczytać w witrynie internetowej sqlite. Instrukcje SQL są uruchamiane przy użyciu jednej z trzech metod w obiekcie SqliteCommand:

  • ExecuteNonQuery — zwykle używany do tworzenia tabeli lub wstawiania danych. Wartość zwracana dla niektórych operacji to liczba wierszy, których dotyczy problem, w przeciwnym razie wynosi -1.
  • ExecuteReader — używany podczas zwracania kolekcji wierszy jako SqlDataReader .
  • ExecuteScalar — pobiera pojedynczą wartość (na przykład agregację).

EXECUTENONQUERY

Instrukcje INSERT, UPDATE i DELETE będą zwracać liczbę wierszy, których dotyczy problem. Wszystkie inne instrukcje SQL będą zwracać wartość -1.

using (var c = connection.CreateCommand ()) {
    c.CommandText = "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'APPL')";
    var rowcount = c.ExecuteNonQuery (); // rowcount will be 1
}

EXECUTEREADER

Poniższa metoda przedstawia klauzulę WHERE w instrukcji SELECT. Ponieważ kod tworzy pełną instrukcję SQL, należy zadbać o ucieczkę znaków zarezerwowanych, takich jak cudzysłów (') wokół ciągów.

public static string MoreComplexQuery ()
{
    var output = "";
    output += "\nComplex query example: ";
    string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal), "ormdemo.db3");

    connection = new SqliteConnection ("Data Source=" + dbPath);
    connection.Open ();
    using (var contents = connection.CreateCommand ()) {
        contents.CommandText = "SELECT * FROM [Items] WHERE Symbol = 'MSFT'";
        var r = contents.ExecuteReader ();
        output += "\nReading data";
        while (r.Read ())
            output += String.Format ("\n\tKey={0}; Value={1}",
                    r ["_id"].ToString (),
                    r ["Symbol"].ToString ());
    }
    connection.Close ();

    return output;
}

Metoda ExecuteReader zwraca obiekt SqliteDataReader. Oprócz metody Read pokazanej w przykładzie inne przydatne właściwości to:

  • Wiersze, których dotyczy problem — liczba wierszy, których dotyczy zapytanie.
  • HasRows — czy zostały zwrócone jakiekolwiek wiersze.

EXECUTESCALAR

Użyj tej opcji dla instrukcji SELECT, które zwracają pojedynczą wartość (np. agregację).

using (var contents = connection.CreateCommand ()) {
    contents.CommandText = "SELECT COUNT(*) FROM [Items] WHERE Symbol <> 'MSFT'";
    var i = contents.ExecuteScalar ();
}

Zwracany ExecuteScalar typ metody to object — należy rzutować wynik w zależności od zapytania bazy danych. Wynikiem może być liczba całkowita z zapytania COUNT lub ciąg z pojedynczej kolumny zapytania SELECT. Należy pamiętać, że różni się to od innych metod Execute, które zwracają obiekt czytelnika lub liczbę wierszy, których dotyczy problem.

Microsoft.Data.Sqlite

Istnieje inna biblioteka Microsoft.Data.Sqlite, którą można zainstalować z pakietu NuGet, która jest funkcjonalnie równoważna Mono.Data.Sqlite i umożliwia wykonywanie tych samych typów zapytań.

Istnieje porównanie dwóch bibliotek i niektórych szczegółów specyficznych dla platformy Xamarin. Najważniejsze dla aplikacji platformy Xamarin.iOS należy dołączyć wywołanie inicjowania:

// required for Xamarin.iOS
SQLitePCL.Batteries_V2.Init();