エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 のローカル データベース

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

Windows Phone OS 7.1 以降、アプリのローカル フォルダーに存在するローカル データベースにリレーショナル データを格納できます。Windows Phone アプリはすべてのデータベース操作に LINQ to SQL を使用します。LINQ to SQL は、データベース スキーマを定義し、データを選択し、ローカル フォルダー内に存在する基のデータベース ファイルに変更を保存するのに使用されます。このトピックでは、Windows Phone アプリにおけるローカル データベースの使用について概要を説明します。ローカル データベースを使用するアプリを作成する詳細なチュートリアルについては、「Windows Phone 8 の基本的なローカル データベース アプリを作成する方法」を参照してください。

このトピックは、次のセクションで構成されています。

ローカル データベースでデータの格納および取得を行うには、Windows Phone アプリで LINQ to SQL を使用します。LINQ to SQL は、オブジェクト指向式のデータの操作を可能にするもので、オブジェクト モデルとランタイムで構成されます。

LINQ to SQL オブジェクト モデルは主に、ローカル データベースのプロキシとして機能する System.Data.Linq.DataContext オブジェクトによって構成されます。LINQ to SQL ランタイムは、データ (ローカル データベース) の世界とオブジェクト (DataContext オブジェクト) の世界を橋渡しする役割を担っています。この関係は、次の図のようにまとめることができます。

Windows Phone DataContext and Local Database

データ コンテキストは、データベースを表すオブジェクトであるプロキシです。データ コンテキストには、ぞれぞれがデータベース内のテーブルを表すTable オブジェクトが含まれます。各 Table オブジェクトは、データベース内のデータ行に対応するエンティティで構成されます。各エンティティは、属性を備えた POCO (Plain Old CLR Object) です。各エンティティの属性により、データベース テーブルの構造が決まり、データのオブジェクト モデルとデータベースのスキーマとの間のマッピングが定義されます。たとえば、Name プロパティと PhoneNumber プロパティを有するエンティティは、Name 列と PhoneNumber 列を持つデータベース テーブルになります。

LINQ to SQL では、オブジェクトリレーショナル マッピング機能が利用できます。この機能を使用すると、マネージ アプリで統合言語クエリ (LINQ) を使用してリレーショナル データベース (Transact-SQL のみ使用) と通信することができます。LINQ to SQL は、.NET Framework マネージ コードで表現したオブジェクト モデルを、リレーショナル データベースにマッピングします。アプリを実行すると、LINQ to SQL は統合言語クエリを Transact-SQL に変換してから、それらのクエリをデータベースに送信して実行します。データベースから結果が返されると、LINQ to SQL は返された結果をそれぞれのプログラミング言語で操作できるオブジェクトに変換します。詳細については、「LINQ to SQL」を参照してください。

メモメモ:

Windows Phone の LINQ to SQL は、データ定義言語 (DDL) ステートメントやデータ モデリング言語 (DML) ステートメントを含めて、Transact-SQL の実行を直接サポートしていません。また、Windows Phone アプリでは、LINQ to SQL を使用して ADO.NET オブジェクトに直接アクセスすることはできません。詳細については、「Windows Phone 8 での LINQ to SQL のサポート」を参照してください。

SQL Server のリレーショナル データベースを使用するデスクトップ アプリと同様に、Windows Phone アプリは、LINQ to SQL を使用することにより、ローカル データベースを使用して、データの選択、挿入、更新、および削除を行うことができます。これにより、Windows Phone アプリでは、LINQ の強力なクエリ機能と、ストレージ効率に優れたリレーショナル データベースを利用することができます。電話に搭載されたリソースは PC よりも少ないため、ローカル データベースは一般的なデータベースといくつかの点で異なっています。相違点は次のとおりです。

  • ローカル データベースは、Windows Phone アプリのプロセスで実行されます。Microsoft SQL Server などのクライアントサーバー型データベースと異なり、バックグラウンド サービスとして連続して実行されることはありません。

  • ローカル データベースは、対応する Windows Phone アプリからのみアクセス可能です。データベース ファイルはローカル フォルダーに存在するため、他のアプリからこのデータにアクセスすることはできません。

  • ローカル データベースは LINQ to SQL でのみアクセス可能です。Transact-SQL はサポートされていません。

標準のアプリの展開では、アプリの初回実行時に、ローカル フォルダー内にローカル データベースが作成されます。その後、アプリが使用されるたびに、このデータベースにアプリ データが追加されます。アプリと一緒に事前設定される一連の参照データを含めるには、アプリにローカル データベース ファイルを追加します。詳細な手順については、「Windows Phone 8 用のアプリで参照データベースを展開する方法」を参照してください。

アプリと一緒に参照データを展開するには、以下の手順を実行する必要があります。

  1. ヘルパー アプリケーションの作成: ヘルパー アプリは、開発コンピューター上で実行され、ローカル フォルダーにローカル データベースを作成し、そのデータベースに必要な参照データを読み込みます。

  2. ヘルパー アプリケーションからローカル データベースを抽出: 分離ストレージ エクスプローラー (ISETool.exe) を使用して、ヘルパー アプリからコンピューター上のフォルダーにデータベースをコピーします。分離ストレージ エクスプローラーの詳細については、「Windows Phone 8 の分離ストレージ エクスプローラー ツールを使用する方法」を参照してください。

  3. プライマリ アプリケーションの作成: 参照データを使用するアプリを作成します。

  4. プライマリ アプリケーションに参照データを追加: Visual Studio を使用して、コンピューター上の保存先フォルダーからローカル データベース ファイルをプライマリ アプリに追加します。アプリのアセンブリのサイズを最小にするには、ファイルをコンテンツとして保存します。

ローカル データベースがアプリと一緒に展開されると、読み取り専用状態でインストール フォルダー内に置かれます。インストール フォルダーはローカル フォルダーとは異なります。この場所のデータベース ファイルをアドレス指定するには、appdata: プレフィックスを使用します。データベース接続文字列でこのプレフィックスを使用する例については、「Windows Phone 8 のローカル データベース接続文字列」を参照してください。

重要:重要:

インストール フォルダーからのみ参照データベース ファイルへアクセスする場合は、データベースを暗号化することはお勧めしません。暗号化すると、最初の接続時にシステムによる所定のデータベースの保守作業 (インデックスの再作成など) を行えなくなります。暗号化された参照データベースを使用するには、使用する前にローカル フォルダーにコピーしてから、読み取り/書き込みモードで接続します。データベースをコピーする方法の詳細については、「Windows Phone 8 用のアプリで参照データベースを展開する方法」を参照してください。

参照データを格納するデータベースを変更するには、インストール フォルダーからデータベースを移動し、ローカル フォルダーに保存してから、データベースを変更します。データベース ファイルを移動するには、Application.GetResourceStream メソッドでインストール フォルダーからストリームを作成し、IsolatedStorageFileStream.Write メソッドでローカル フォルダーにストリームを書き込むことによって、ストリーム ベースのコピーを実行できます。次の例に、ストリーム オブジェクトを作成する場合にインストール フォルダー内のデータベース ファイルをアドレス指定する方法を示します。

Stream str = Application.GetResourceStream(new Uri("appdata:/MyReferenceDB.sdf", UriKind.Relative)).Stream;

ローカル データベースを作成するには、最初にデータ コンテキストとエンティティを定義する必要があります。これらのクラスでは、データのオブジェクト モデルとデータベースのスキーマとの間のマッピングを定義します。LINQ to SQL のオブジェクトリレーショナル機能は、対応するデータ コンテキストにマッピングされるリレーショナル データベースを作成する際、これらのマッピングの詳細情報に依存します。

エンティティごとに、LINQ to SQL のマッピング属性を使用してマッピングの詳細が指定されます。これらの属性では、テーブル、列、主キー、およびインデックスなどのデータベースごとの機能が指定されます。詳細については、「属性ベースの対応付け (LINQ to SQL)」を参照してください。 たとえば、次のコードは、ToDoDataContext という名前のデータ コンテキストと、ToDoItem という名前のエンティティ クラスの最初の部分を示しています。

public class ToDoDataContext : DataContext
{
    // Specify the connection string as a static, used in main page and app.xaml.
    public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";

    // Pass the connection string to the base class.
    public ToDoDataContext(string connectionString): base(connectionString) { }

    // Specify a single table for the to-do items.
    public Table<ToDoItem> ToDoItems;
}

// Define the to-do items database table.
[Table]
public class ToDoItem : INotifyPropertyChanged, INotifyPropertyChanging
{
    // Define ID: private field, public property, and database column.
    private int _toDoItemId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int ToDoItemId
    {
        get
        {
            return _toDoItemId;
        }
        set
        {
            if (_toDoItemId != value)
            {
                NotifyPropertyChanging("ToDoItemId");
                _toDoItemId = value;
                NotifyPropertyChanged("ToDoItemId");
            }
        }
    }
         . . .
         . . .
         . . .

メモメモ:

これは、データ コンテキスト コードの一部です。ローカル データベースを使用するアプリを作成する詳細なチュートリアルについては、「Windows Phone 8 の基本的なローカル データベース アプリを作成する方法」を参照してください。

各自のコードでローカル データベース機能を使用する場合は、コード ファイルの先頭に次のディレクティブが必要になります。


using System.Data.Linq;
using System.Data.Linq.Mapping;
using Microsoft.Phone.Data.Linq;
using Microsoft.Phone.Data.Linq.Mapping;

LINQ to SQL の一般的なマッピング属性の一部を次の表に示します。完全な一覧については、「System.Data.Linq.Mapping」を参照してください。

属性

説明

TableAttribute

[Table]

データベース テーブルに関連付けられたエンティティ クラスとしてクラスを指定します。

ColumnAttribute

[Column(IsPrimaryKey = true)]

データベース テーブルの列にクラスを関連付けます。IsPrimaryKey は主キーを指定します。主キーには、既定でインデックスが作成されます。

IndexAttribute

[Index(Columns="Column1,Column2 DESC", IsUnique=true, Name="MultiColumnIndex")]

テーブル レベルで記述します。テーブルの追加インデックスを指定します。各インデックスは 1 つまたは複数の列をカバーすることができます。

AssociationAttribute

[Association(Storage="ThisEntityRefName", ThisKey="ThisEntityID", OtherKey="TargetEntityID")]

外部キーと主キーの関連付けなどの、関連付けを表すプロパティを指定します。

DataContext オブジェクトを作成した後、ローカル データベースを作成し、各種データベース操作を実行することができます。ToDoDataContext クラスのデータ コンテキストに基づいて、データベースを作成するコード例を次に示します。

// Create the database if it does not yet exist.
using (ToDoDataContext db = new ToDoDataContext("isostore:/ToDo.sdf"))
{
    if (db.DatabaseExists() == false)
    {
        // Create the database.
        db.CreateDatabase();
    }
}

この例に示すように、データ コンテキストを作成するには、最初にデータ コンテキストとデータベース ファイルのファイルの場所を指定する必要があります。DataContext のコンストラクターの値は、データベース ファイル名が ToDo.sdf であることを指定しています。この値の isostore:/ 部分は、ファイルがローカル フォルダーに存在することを示しています。次に、DatabaseExists メソッドでデータベースがまだ存在していないことを確認してから、CreateDatabase メソッドを使用してデータベースを作成します。

メモメモ:

作成したデータベースには、自動的にバージョン 0 が割り当てられます。データベースのバージョンを判別するには、DatabaseSchemaUpdater クラスを使用します (このトピックで後述する「データベース スキーマの変更」を参照してください)。

ローカル データベースの作成が完了したら、LINQ とデータ コンテキストを使用して、ローカル データベースを使用することができます。以下のサブセクションでは、データベースのデータを選択、挿入、更新、および削除する方法について説明します。これらの操作を実行するアプリを作成する詳細なチュートリアルについては、「Windows Phone 8 の基本的なローカル データベース アプリを作成する方法」を参照してください。

データの選択 (データベース クエリ)

Windows Phone では、データベースのクエリに統合言語クエリ (LINQ) を使用します。LINQ はオブジェクトの世界とデータの世界の橋渡しをします。LINQ to SQL のクエリでは、LINQ のクエリと同じ構文を使用します。LINQ クエリの詳細については、「LINQ クエリの概要 (C#)」を参照してください。

LINQ to SQL のクエリで参照されるオブジェクトは、データベース内のレコードにマッピングされます。そのため、LINQ to SQL はクエリの実行方法が他の LINQ テクノロジと異なります。一般的な LINQ クエリは、メモリ内のアプリケーション層で実行されます。LINQ to SQL では、ランタイムのオブジェクト リレーショナル機能を使用して、各 LINQ クエリを Transact-SQL に変換してから、データベース内で直接実行します。これにより、大容量のデータベースから少数のレコードを選択するようなクエリで、パフォーマンスの向上を実現することができます。

次の例では、toDoDB という名前の DataContext オブジェクトが LINQ to SQL で照会され、結果が ToDoItems という名前の ToDoItem オブジェクトの ObservableCollection に書き込まれます。遅延実行により、ToDoItems コレクションがインスタンス化されるまで、データベース クエリは実際には実行されません。

// Define query to gather all of the to-do items.
var toDoItemsInDB = from ToDoItem todo in toDoDB.ToDoItems
                    select todo;

// Execute query and place results into a collection.
ToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);

データの挿入

データベースへのデータの挿入は 2 段階の処理で実行されます。最初にデータ コンテキストにオブジェクトを追加し、次にデータ コンテキストの SubmitChanges メソッドを呼び出して、データベース内の行としてデータを保持します。詳細については、「方法: 行をデータベースに挿入する (LINQ to SQL)」を参照してください。

次の例では、ToDoItem オブジェクトを作成し、toDoDB という名前のデータ コンテキストの ToDoItems オブザーバブル コレクションおよび対応するデータベース テーブルに追加しています。

// Create a new to-do item based on text box.
ToDoItem newToDo = new ToDoItem { ItemName = newToDoTextBox.Text };

// Add the to-do item to the observable collection.
ToDoItems.Add(newToDo);
            
// Add the to-do item to the local database.
toDoDB.ToDoItems.InsertOnSubmit(newToDo); 

重要:重要:

SubmitChanges メソッドが呼び出されるまで、データはデータベースに保存されません。

データの更新

ローカル データベースのデータの更新は、3 段階で行われます。最初に、データベースで更新対象のオブジェクトをクエリします。次に、必要に応じてオブジェクトを変更します。最後に、SubmitChanges メソッドを呼び出してローカル データベースの変更を保存します。詳細については、「方法: 行をデータベースに挿入する (LINQ to SQL)」を参照してください。

データ コンテキストのオブジェクトをページ上のコントロールにバインドすると、ユーザーの操作に基づいてデータ コンテキストを自動的に更新することができます。この場合、必要なときに SubmitChanges メソッドを呼び出すだけで済みます。この手法の例は、ローカル データベースのサンプル アプリにあります。「Windows Phone 8 の基本的なローカル データベース アプリを作成する方法」を参照してください。ユーザーがページから移動したときに、SubmitChanges メソッドを呼び出すコード例を次に示します。

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{ 
    //Call base method
    base.OnNavigatedFrom(e);
            
    //Save changes to the database
    toDoDB.SubmitChanges();
}
重要:重要:

SubmitChanges メソッドが呼び出されるまで、データベース内のデータは更新されません。

データの削除

データベース内のデータの削除も、3 つの手順で構成されます。最初に、データベースで削除対象のオブジェクトをクエリします。次に、削除するオブジェクトが 1 つか複数かに応じて、DeleteOnSubmit または DeleteAllOnSubmit メソッドを呼び出し、該当するオブジェクトを削除保留状態にします。最後に、SubmitChanges メソッドを呼び出してローカル データベースの変更を保存します。詳細については、「方法: 行をデータベースから削除する (LINQ to SQL)」を参照してください。

次の例では、ToDoItem オブジェクトが toDoDB という名前のデータベースから削除されます。オブジェクトが 1 つだけ削除されるため、SubmitChanges の前に DeleteOnSubmit メソッドが呼び出されます。

//Get a handle for the to-do item bound to the button
ToDoItem toDoForDelete = button.DataContext as ToDoItem;

//Remove the to-do item from the observable collection
ToDoItems.Remove(toDoForDelete);

//Remove the to-do item from the local database
toDoDB.ToDoItems.DeleteOnSubmit(toDoForDelete);

//Save changes to the database
toDoDB.SubmitChanges();

重要:重要:

SubmitChanges メソッドが呼び出されるまで、データベースからデータは削除されません。

Windows Phone アプリを変更する場合、ローカル データベース スキーマの変更が必要になる場合があります。ローカル データベース スキーマを変更する場合は、対応するデータ コンテキストのオブジェクト モデルを変更することから開始します。Microsoft.Phone.Data.Linq 名前空間に、データベース スキーマの変更に役立つ DatabaseSchemaUpdater クラスが用意されています。このクラスの使用例については、「チュートリアル: Windows Phone 8 のローカル データベース アプリを更新する」を参照してください。

DatabaseSchemaUpdater クラスでは、テーブル、列、インデックス、または関連付けの追加など、データベースに対する追加的な変更を実行できます。より複雑な変更を行う場合は、必要に応じて、データベースを新規に作成し、新しいスキーマにデータをコピーする必要があります。DatabaseSchemaUpdater クラスでは DatabaseSchemaVersion プロパティが利用できます。このプロパティを使用すると、データベースの各種バージョンをプログラムで区別することができます。

重要:重要:

Execute メソッドが呼び出されるまでは、DatabaseSchemaUpdater オブジェクトからの更新を反映するデータベースの変更は行われません。このメソッドが呼び出されると、バージョンの更新も含め、すべての変更が 1 つのトランザクションとしてローカル データベースに送信されます。1 つのトランザクションを使用することによって、ユーザーがアップグレード中にアプリを終了した場合などに、データベースの整合性が維持されます。

次に、DatabaseSchemaUpdater クラスを使用し、DatabaseSchemaVersion プロパティに基づいてデータベースを変更する例を示します。

using (ToDoDataContext db = new ToDoDataContext(("isostore:/ToDo.sdf")))
{
        //Create the database schema updater
        DatabaseSchemaUpdater dbUpdate = db.CreateDatabaseSchemaUpdater();

        //Get database version
        int dbVersion = dbUpdate.DatabaseSchemaVersion;

        //Update database as applicable
        if (dbVersion < 5)
        {   //Copy data from existing database to new database 
            MigrateDatabaseToLatestVersion();
        }
        else if (dbVersion == 5)
        {   //Add column to existing database to match the data context
            dbUpdate.AddColumn<ToDoItem>("TaskURL");
            dbUpdate.DatabaseSchemaVersion = 6;
            dbUpdate.Execute();
        }
}

メモメモ:

ローカル フォルダーに保存されたファイル (ローカル データベース ファイルを含む) は、アプリケーションの更新中には変更されません。

ローカル データベースでは、パスワード保護と暗号化を利用してデータベースを保護することができます。データベースでパスワードを使用すると、データベース全体が暗号化されます。データベースを暗号化するには、データベースを作成する前にデータベース接続文字列 (データ コンテキスト コンストラクター) でパスワードを提供します。パスワードはデータベースにアクセスするたびに入力する必要があります。作成済みのデータベースを暗号化することはできません。データベースは AES-128 を使用して暗号化され、パスワードは SHA-256 を使用してハッシュされます。

次に、データベース接続文字列でパスワードを指定して、暗号化されたデータベースを作成する例を示します。

// Create the data context, specify the database file location and password
ToDoDataContext db = new ToDoDataContext ("Data Source=’isostore:/ToDo.sdf’;Password=’securepassword’");

// Create an encrypted database after confirming that it does not exist
if (!db.DatabaseExists()) db.CreateDatabase();

ヒントヒント:

インデックス付きでない列の一部のみを暗号化する必要がある場合は、データベース全体を暗号化せずに、データベースに追加する前に該当データを暗号化することで、パフォーマンスの向上させることができます。データを暗号化する方法の詳細については、「Windows Phone 8 でデータを暗号化する方法」を参照してください。

ローカル データベースでの接続文字列の使用についての詳細は、「Windows Phone 8 のローカル データベース接続文字列」を参照してください。

表示:
© 2014 Microsoft