オブジェクトモデルの変更 - .NET SDK
Overview
移行により、既存の Realm とそのオブジェクトが現在の Realm スキーマ バージョンから新しいバージョンに変換されます。 アプリケーション データモデルは通常、新しい要件や機能に対応するために時間の経過とともに変化します。 移行により、クライアント アプリケーションが新しいバージョンにアップグレードするたびに、既存のアプリケーション データを自動的に更新する柔軟性が付与されます。
次の例えを考えてみます。ここでは、「権限」と呼ばれる RealmObject
があるので、
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public int Age { get; set; } }
たとえば、 FullName
プロパティをFirstName
とLastName
の 2 つの個別のプロパティに分割するとします。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } }
この時点で、モデルと保存されたデータの間で不一致が発生し、Realm を開こうとすると例外がスローされます。
スキーマ バージョン
スキーマ バージョンは、ある時点におけるRealm スキーマの状態を識別します。 Realm は各 Realm のスキーマ バージョンを追跡し、それを使用して各 Realm 内のオブジェクトを正しいスキーマにマッピングします。
スキーマ バージョンは、Realm を開くときに Realm 構成に含めることができる整数です。 クライアント アプリケーションが Realm を開くときにバージョン番号を指定しない場合、Realm はデフォルトでバージョン0
になります。
重要
バージョンを単調に増加させる
移行によって、Realm をより高いスキーマ バージョンに更新する必要があります。 Realm は、Realm の現在のバージョンよりも低いスキーマ バージョンでクライアント アプリケーションが Realm を開き、または指定されたスキーマ バージョンが Realm の現在のバージョンと同じであるが、異なるオブジェクト スキーマを含む場合にエラーをスローします。
スキーマの移行
次の例は、スキーマ内でプロパティを追加、削除、および変更する方法を示しています。 まず、必要なスキーマを変更します。 次に、元のスキーマから更新されたスキーマにデータを移動するための対応する移行関数を作成します。
注意
同期された Realm のスキーマ プロパティの変更
次のページでは、ローカル Realm のスキーマ プロパティを変更する方法を示します。 同期された Realm のスキーマ プロパティを変更する方法を学習します。
注意
Realm Open でのバージョン更新
この例の各スキーマの変更は、アプリケーションが各バージョンを一定時間使用した後に発生すると想定します。 新しいスキーマのバージョン番号は、更新されたスキーマで Realm を開き、新しいバージョン番号を明示的に指定した場合にのみ適用されるため、バージョン 3 に達するには、まずバージョン 1 と 2 でアプリを開く必要があります。
スキーマ バージョン1
を使用する Realm のオブジェクトタイプはPerson
です。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public int Age { get; set; } }
プロパティを追加する
次の例では、元の Response スキーマにLastName
プロパティを追加しています。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } }
プロパティを削除する
次の例では、元の people スキーマの個別のFirstName
プロパティとLastName
プロパティではなく、結合されたFullName
プロパティを使用します。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public int Age { get; set; } }
プロパティタイプの変更またはプロパティの名前変更
次の例では、名前をBirthday
に変更し、 タイプをDateTimeOffset
に変更することで、元の Python スキーマのAge
プロパティを変更します。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public DateTimeOffset Birthday { get; set; } }
移行関数
Tip
開発中のバイパス移行
アプリケーションを開発またはデバッグする際には、Realm を移行するのではなく、Realm を削除することをお勧めします。 スキーマの不一致により移行が必要になる場合に、 ShouldDeleteIfMigrationNetedフラグを使用してデータベースを自動的に削除します。
このフラグをtrue
に設定して本番環境にアプリをリリース しないでください 。
更新されたPerson
スキーマに準拠するように Realm を移行するには、Realm のスキーマ バージョンを4
に設定し、既存のFirstName
とLastName
プロパティに基づいてFullName
の値を設定するための移行関数を定義します。 Age
に基づくBirthday
の値:
1 var config = new RealmConfiguration 2 { 3 SchemaVersion = 4, 4 MigrationCallback = (migration, oldSchemaVersion) => 5 { 6 var oldVersionPeople = migration.OldRealm.DynamicApi.All("Person"); 7 var newVersionPeople = migration.NewRealm.All<Person>(); 8 9 // Migrate Person objects 10 for (var i = 0; i < newVersionPeople.Count(); i++) 11 { 12 var oldVersionPerson = oldVersionPeople.ElementAt(i); 13 var newVersionPerson = newVersionPeople.ElementAt(i); 14 15 // Changes from version 1 to 2 (adding LastName) will 16 // occur automatically when Realm detects the change 17 18 // Migrate Person from version 2 to 3: 19 // Replace FirstName and LastName with FullName 20 // LastName doesn't exist in version 1 21 var firstName = oldVersionPerson.DynamicApi.Get<string>("FirstName"); 22 var lastName = oldVersionPerson.DynamicApi.Get<string>("LastName"); 23 24 if (oldSchemaVersion < 2) 25 { 26 newVersionPerson.FullName = firstName; 27 } 28 else if (oldSchemaVersion < 3) 29 { 30 newVersionPerson.FullName = $"{firstName} {lastName}"; 31 } 32 33 // Migrate Person from version 3 to 4: replace Age with Birthday 34 if (oldSchemaVersion < 4) 35 { 36 var birthYear = 37 DateTimeOffset.UtcNow.Year - oldVersionPerson.DynamicApi.Get<int>("Age"); 38 newVersionPerson.Birthday = 39 new DateTimeOffset(birthYear, 1, 1, 0, 0, 0, TimeSpan.Zero); 40 } 41 } 42 } 43 }; 44 var realm = Realm.GetInstance(config);