オブジェクトモデルの作成
Realm クラスは、Realm スキーマを定義する通常の C# クラスです。
重要
継承
すべての Realm オブジェクトは、 IRealmObject 、 IEMededObject 、またはIAmetricObjectインターフェースから継承し、 partialクラスを宣言する必要があります。
10.18.0より前のバージョンの .NET SDK では、 オブジェクトは、 RealmObject 、埋め込みオブジェクト 、またはAmetricObject基本クラスから派生します。 Realm モデル定義へのこのアプローチは引き続きサポートされていますが、 null 可能性注釈などの新機能は含まれていません。 将来の SDK リリースでは、基本クラスは非推奨になる予定です。 作成する新しいクラスには インターフェースを使用し、既存のクラスの移行を検討する必要があります。
注意
クラス名は最大 57 文字の UTF-8 文字に制限されています。
オブジェクト スキーマ
オブジェクト スキーマは、Realm オブジェクトのプロパティと関係を定義する構成オブジェクトです。 Realm クライアント アプリケーションは、 オブジェクト スキーマを使用して、それぞれの言語のネイティブ クラス実装でオブジェクト スキーマを定義します。
オブジェクト スキーマは、各プロパティのデータ型やプロパティが必要かどうかなど、オブジェクト プロパティに関する制約を指定します。 スキーマは、Realm 内のオブジェクトタイプ間の関係を定義することもできます。
すべてのアプリには、そのアプリケーション内の Realm に含まれる可能性のある各オブジェクト タイプのオブジェクト スキーマのリストで構成されるApp Services スキーマがあります。 Realm は、Realm 内のすべてのオブジェクトがオブジェクトタイプのスキーマに準拠していることを保証し、オブジェクトが作成、変更、または削除されるたびにオブジェクトを検証します。
プロパティ注釈
スキーマ プロパティは、 RealmObject上の標準 C# プロパティです。 Realm が特定のプロパティを処理する方法をより詳細に定義するために使用できるプロパティ注釈がいくつかあります。
プライマリキー
プライマリキーは、オブジェクトを一意に識別するプロパティです。 次のいずれかのタイプ(または null 可能なカウンターポート)でプライマリキーを作成できます。
ObjectIdUUIDstringcharbyteshortintlong
オブジェクト スキーマ の一部として、オブジェクトタイプの 単一のプロパティ にプライマリキーを定義できます。Realm はプライマリキー プロパティを自動的にインデックス化します。これにより、プライマリキーに基づいてオブジェクトを効率的に読み取り、変更できます。
オブジェクトタイプにプライマリキーがある場合、そのタイプのすべてのオブジェクトには、Realm 内の同じタイプのオブジェクト間で一意の値を持つプライマリキー プロパティが含まれている必要があります。
注意
プロパティをプライマリキーとして割り当てると、それを変更することはできません。
次の例は、オブジェクト スキーマでプライマリキーを指定する方法を示しています。
public partial class Dog : IRealmObject { [] public string Name { get; set; } public int Age { get; set; } public Person? Owner { get; set; } }
Indexes
インデックスにより、Realm でのクエリ時間が大幅に改善されます。 インデックスがない場合、Realm はコレクション内のすべてのドキュメントをスキャンして、指定されたクエリに一致するドキュメントを選択します。 ただし、クエリに該当するインデックスが存在する場合は、Realm ではそのインデックスを使用して検査する必要があるドキュメントの数が制限されます。
次のタイプのプロパティをインデックスできます。
boolbyteshortintlongDateTimeOffsetcharstringObjectIdUUID
注意
インデックスを追加すると、クエリが高速化されますが、書込み時間がわずかに遅くなり、ストレージとメモリのオーバーヘッドが増加します。 インデックスには Realm ファイル内に領域が必要になるため、プロパティにインデックスを追加すると、Realm ファイルで消費されるディスク容量が増加します。 各インデックスエントリは 12 バイト以上です。
プロパティをインデックスするには、 Indexed属性を使用します。 Indexed属性では、 IndexType列挙型を使用してプロパティのインデックスのタイプを指定できます。 次の例では、 Nameプロパティにデフォルト(「一般」)のインデックスがあります。
public partial class Person : IRealmObject { [] public string Name { get; set; } [] public string Biography { get; set; } }
注意
インデックスを作成する際、そのインデックスは Atlas コレクションではなくローカル レルムに作成されます。 Atlas コレクションを直接クエリする必要があり、パフォーマンスを向上させたい場合は、「 インデックスの作成、表示、削除、非表示 」を参照してください。
全文検索インデックス
標準インデックスに加えて、Realm はstringプロパティで全文検索(FTS)インデックスもサポートしています。 標準インデックスの有無にかかわらず string フィールドをクエリできますが、FTS インデックスを使用すると複数の単語とフレーズを検索し、その他を除外できます。
全文インデックスのクエリの詳細については、「 Full Text Search (LINQ) 」およびFull Text Search ( RQL ) 」を参照してください。
FTS プロパティをインデックス化するには、 IndexType.FullText 列挙型の インデックス付き 属性 を使用します。In the following example, we have a FullText index on the Biography property:
public partial class Person : IRealmObject { [] public string Name { get; set; } [] public string Biography { get; set; } }
デフォルトのフィールド値
組み込みの言語機能を使用して、プロパティにデフォルト値を割り当てることができます。 C# では、プロパティ宣言でプリミティブにデフォルト値を割り当てることができます。 コレクションにデフォルト値を設定することはできません。ただし、 null!に設定する場合を除きます。 コレクションをnull!に設定しても、コレクションは最初のアクセス時に常に初期化されるため、null になることはありません。
public partial class Person : IRealmObject { public string Name { get; set; } = "foo"; public IList<PhoneNumber> PhoneNumbers { get; } = null!; }
注意
デフォルト値と null 可能性
デフォルト値により、新しく作成されたオブジェクトにnullの値を含めることはできませんが(デフォルト値としてnullを指定しない限り)、プロパティの null 可能性には影響しません。 To make a property non-nullable, see Required Properties.
プロパティを無視
モデル内のプロパティを Realm に保存したくない場合は、そのプロパティを無視できます。 プロパティが自動実装されていないか、セッターがない場合、デフォルトでは無視されます。
Ignored属性を持つ Realm オブジェクトモデルからプロパティを無視します。
// Rather than store an Image in Realm, // store the path to the Image... public string ThumbnailPath { get; set; } // ...and the Image itself can be // in-memory when the app is running: [] public Image? Thumbnail { get; set; }
プロパティの名前を変更する
デフォルトでは、Realm はモデル クラスで定義された名前を使用して、プロパティを内部的に表します。 場合によっては、この動作を変更する必要があるかもしれません。
命名規則が異なるプラットフォーム間での操作を容易にするため。
移行を強制せずに .NET でプロパティ名を変更します。
モデル クラスで使用される名前とは異なる内部名を選択する場合、次の影響があります。
移行では、クラスとプロパティを作成するときに内部名を使用する必要があります。
報告されたスキーマ エラーでは内部名が使用されます。
[MapTo]属性を使用して、プロパティの名前を変更します。
public partial class Person : IRealmObject { [] public string Name { get; set; } }
クラス名の変更
デフォルトでは、Realm はモデル クラスで定義された名前を使用して内部クラスを表します。 場合によっては、この動作を変更する必要があるかもしれません。
異なる名前空間で同じ単純名を持つ複数のモデル クラスをサポートします。
命名規則が異なるプラットフォーム間での操作を容易にするため。
Realm によって強制される 57 文字の制限よりも長いクラス名を使用します。
移行を強制せずに .NET でクラス名を変更するには
[MapTo]属性を使用して、クラスの名前を変更します。
[] public partial class Person : IRealmObject { public string Name { get; set; } }
カスタム セッター
Realm は、カスタム 設定を含むプロパティを保存しません。 カスタム セッターを使用するには、プロパティ値をプライベート プロパティに保存し、その値をカスタム セッターでパブリック プロパティにマッピングします。 Realm はプライベート プロパティを保存し、パブリック プロパティを使用してその値を変更します。 次のコードでは、プライベートemailプロパティは Realm に保存されていますが、検証を提供するパブリックEmailプロパティは永続化されていません。
// This property will be stored in the Realm private string email { get; set; } // Custom validation of the email property. // This property is *not* stored in Realm. public string Email { get { return email; } set { if (!value.Contains("@")) throw new Exception("Invalid email address"); email = value; } }
非構造化データの定義
バージョン12.2.0の新機能。
SDK バージョン12.2.0以降、 RealmValueプロパティ内に混合データのコレクションを保存できます。 この機能を使用すると、厳密なデータモデルを定義することなく、JSON や MongoDB ドキュメントなどの複雑なデータ構造をモデル化できます。
非構造化データとは、期待されるスキーマに簡単に準拠していないデータであるため、個々のデータ クラスにモデル化するのが困難または非効率的です。 たとえば、アプリには、実行時に構造が不明な高度に変数データや動的データがある場合があります。
コレクションを混合プロパティに保存すると、Device Sync を使用する際のパフォーマンス的な同期など、機能を犠牲にすることなく柔軟性が高まります。 そして、混合されていないコレクションと同じ方法でそれらを操作できます。
混合コレクションは最大100レベルまでネストできます。
混合コレクションのReactに対応する と をクエリできます。
個々の混合コレクション要素を検索して更新できます。
ただし、混合コレクションにデータを保存する場合、構造化スキーマを使用したり、JSON string を単一の string プロパティに直列化したりする場合よりパフォーマンスが低くなります。
アプリ内の非構造化データをモデル化するには、スキーマ内の適切なプロパティをRealmValue型として定義します。 次に、これらのRealmValueプロパティをRealmValue要素のリストまたは辞書として設定できます。 ただし、 RealmValueはセットまたは埋め込みオブジェクトを表すことが できません。
Tip
型が不明であるが、各値には一意の識別子が付けられる場合は、混合データ型のマップを使用します。
型が不明であるが、オブジェクトの順序に意味がある場合は、混合データ型のリストを使用します。
Realm スキーマからクラスを省略する
デフォルトでは、アプリケーションの Realm スキーマにはIRealmObjectまたはIEmbeddedObjectを実装するすべてのクラスが含まれます。 これらのクラスのサブセットのみを Realm スキーマに含める場合は、必要な特定のクラスを含めるように構成を更新できます。
// Declare your schema partial class LoneClass : IRealmObject { public string Name { get; set; } } class AnotherClass { private void SetUpMyRealmConfig() { // Define your config with a single class var config = new RealmConfiguration("RealmWithOneClass.realm"); config.Schema = new[] { typeof(LoneClass) }; // Or, specify multiple classes to use in the Realm config.Schema = new[] { typeof(Dog), typeof(Cat) }; } }
必須 プロパティと任意のプロパティ
C#では、int や などの値の型は暗黙的に nullbool 以外の値になります。ただし、疑問符(? )表記を使用することで、これらを任意にすることができます。
C# 8.0 以降では、null 可能な参照型が導入されました。 プロジェクトで C# 8.0 以降を使用している場合は、 stringやbyte[]などの参照型を?とともに null可能として宣言することもできます。
注意
.NET 6.0 以降、新しいプロジェクトで null 可能なコンテキストはデフォルトで有効になっています。古いプロジェクトの場合は、手動で有効にできます。詳細については、 https://earn.Microsoft.com/en-us/dotnet/chardin-types/nullable-reference-types#setting-the-nullable-context を参照してください。
Realm .NET SDK は、null 可能性があるコンテキストを完全にサポートしており、null 可能性を使用してプロパティが必須か任意かを判断します。 SDK には次のルールがあります。
Realm では、値型プロパティと参照型プロパティを null 可能として指定しない場合、両方が必要であると想定されます。
?を使用してこれらを null 可能として指定すると、Realm はそれらを任意と見なします。Realm オブジェクトタイプであるプロパティは null 可能として宣言する必要があります。
コレクション(リスト、セット、バックリンク、辞書)を null 可能として宣言することはできませんが、それらのパラメータは次のルールに従って null 可能です。
すべてのタイプのコレクションで、パラメータがプリミティブ(値または参照型)の場合、必須または null 可能です。
リスト、セット、バックリンクの場合、パラメーターが Realm オブジェクトの場合、null にすることはできません。
Realm オブジェクトの値の型を持つ辞書の場合は、値の型パラメータを null 可能として宣言する必要があります。
次のコード スニペットは、これらのルールを示しています。
public partial class Person : IRealmObject { /* Reference Types */ public string NonNullableName { get; set; } public string? NullableName { get; set; } public byte[] NonNullableArray { get; set; } public byte[]? NullableArray { get; set; } /* Value Types */ public int NonNullableInt { get; set; } public int? NullableInt { get; set; } /* Realm Objects */ public Dog? NullableDog { get; set; } // public Dog NonNullableDog { get; set; } // Compile-time error /* Collections of Primitives */ public IList<int> IntListWithNonNullableValues { get; } public IList<int?> IntListWithNullableValues { get; } // public IList<int>? NullableListOfInts { get; } // Compile-time error /* Collections of Realm Objects */ public IList<Dog> ListOfNonNullableObjects { get; } // public IList<Dog>? NullableListOfObjects { get; } // Compile-time error // public IList<Dog?> ListOfNullableObjects { get; } // Compile-time error public ISet<Dog> SetOfNonNullableObjects { get; } // public ISet<Dog>? NullableSetOfObjects { get; } // Compile-time error // public ISet<Dog?> SetOfNullableObjects { get; } // Compile-time error public IDictionary<string, Dog?> DictionaryOfNullableObjects { get; } // public IDictionary<string, Dog> DictionaryOfNonNullableObjects { get; } // Compile-time error // public IDictionary<string, Dog>? NullableDictionaryOfObjects { get; } // Compile-time error [] public IQueryable<Dog> MyDogs { get; } // [Backlink(nameof(Dog.People))] // public IQueryable<Dog?> MyDogs { get; } // Compile-time error }
注意
古いスキーマ型定義(クラスはRealmObject基本クラスから派生している)、または null 可能性が有効になっていない場合は、必須のstringとbyte[]に対して[Required]属性を使用する必要があります。プロパティ。
null 値を無視する
Realmオブジェクトのプロパティの null 可能性をより柔軟に定義したい場合があります。そのためには、グローバル構成ファイルで realm.ignore_objects_nullability = true を設定する必要があります。
realm.ignore_objects_nullabilityを有効にすると、Realm オブジェクトのコレクションを含む Realm オブジェクト プロパティで null 可能性注釈が無視されます。