関係 - .NET SDK
Realm を使用すると、アプリ内のオブジェクトのタイプ間の明示的な関係を定義できます。 関係は、プリミティブ データ型の 1 つではなく、別の Realm オブジェクトを参照するオブジェクト プロパティです。 プロパティタイプを別の Realm クラスに設定して関係を定義します。
重要
継承
すべての Realm オブジェクトは、 IRealmObject 、 IEMededObject 、またはIAmetricObjectインターフェースから継承し、 partial
クラスを宣言する必要があります。
10.18.0より前のバージョンの .NET SDK では、 オブジェクトは、 RealmObject 、埋め込みオブジェクト 、またはAmetricObject基本クラスから派生します。 Realm モデル定義へのこのアプローチは引き続きサポートされていますが、 null 可能性注釈などの新機能は含まれていません。 将来の SDK リリースでは、基本クラスは非推奨になる予定です。 作成する新しいクラスには インターフェースを使用し、既存のクラスの移行を検討する必要があります。
関係は Realm 内の他のオブジェクトへの直接参照であるため、関係データベースとは異なり、関係を定義するためにブリッジ テーブルや明示的な結合は必要ありません。 代わりに、関係を定義するプロパティへの読み取りと書き込みにより、関連オブジェクトにアクセスできます。 Realm は読み取り操作を入力時に遅延して実行するため、関係のクエリは通常のプロパティを読み取るのと同じ程度のパフォーマンスです。
関係プロパティを定義する
オブジェクト間の関係には、次の 3 つのプライマリ タイプがあります。
対 1 の関係
対 1 の関係とは、あるオブジェクトが 1 つの他のオブジェクトのみに特定の方法で関連付けられていることを意味します。 タイプが関連する Realm オブジェクトタイプであるプロパティを指定することにより、オブジェクト スキーマ内のオブジェクトタイプの 1 対 1 の関係を定義します。
例
アプリケーションは次のオブジェクト スキーマを使用して、 dog
プロパティにそのドキュメントを含めることで、人間が 1 台の犬を所有できるかどうかを示すことができます。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string Name { get; set; } public DateTimeOffset Birthdate { get; set; } public Dog? Dog { get; set; } } public partial class Dog : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Breed { get; set; } = String.Empty; }
直接関係をクエリするには、LINQ 構文を使用できます。 1 対 1 の関係をクエリする方法については、次の例を参照してください。
var fidosPerson = realm.All<Person>().FirstOrDefault(p => p.Dog == dog);
対多の関係
対多の関係とは、オブジェクトが複数のオブジェクトに特定の方法で関連していることを意味します。 タイプが関連する Realm オブジェクトタイプのIList<T>
であるプロパティを指定することで、オブジェクトタイプの対多関係を定義します。 ゲッターのみを使用してIList<T>
を定義します。 Realm はプロパティに初めてアクセスしたときにコレクション インスタンスを生成するため、コンストラクターで初期化する必要はありません。
// To add items to the IList<T>: var person = new Person(); person.Dogs.Add(new Dog { Name = "Caleb", Age = 7, Breed = "mutt" });
例
アプリケーションは次のオブジェクト スキーマを使用して、 dog
プロパティにそれらを含めることで、人間が複数の犬を所有できることを示すことができます。
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string Name { get; set; } public DateTimeOffset Birthdate { get; set; } public IList<Dog> Dogs { get; } } public partial class Dog : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Breed { get; set; } = String.Empty; }
人と犬の対多の関係を見るには、人をクエリして、その人の犬を取得します。
var katieAndHerDogs = realm.All<Person>(). Where(p => p.Name == "Katie") .FirstOrDefault();
逆の関係
逆の関係は、定義された 1 対多または 1 多の関係でオブジェクトを参照する他のオブジェクトにオブジェクトをリンクします。 関係の定義は一方向であるため、オブジェクトのモデルでプロパティを逆の関係として明示的に定義する必要があります。
たとえば、「ユーザーが多数のアイテムを持っている」という対多の関係では、「アイテムは 1 人のユーザーに属する」という逆関係は自動的に作成されません。 オブジェクトモデルで逆の関係を指定しない場合は、特定のアイテムに割り当てられているユーザーを検索するために別のクエリを実行する必要があります。
逆の関係を定義するには、オブジェクトモデルで getter 専用のIQueryable<T>
プロパティを定義し、 T
は関係のソースタイプです。このプロパティを[Backlink(sourceProperty)]属性で注釈を付けます。ここで、「sourceProperty " は、関係の反対側にあるプロパティの名前です。 次の例は、「ユーザーが多くのアイテムを持っている」シナリオでこれを行う方法を示しています。
public partial class User : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } = ObjectId.GenerateNewId(); public string Name { get; set; } [ ] public IQueryable<Item> Items { get; } } public partial class Item : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } = ObjectId.GenerateNewId(); public string Text { get; set; } public User? Assignee { get; set; } }
この例では、次のことがわかります。
アイテム オブジェクトの
Assignee
プロパティは ユーザー オブジェクトです。ユーザー オブジェクトの
Items
プロパティは関係を反転させ、Assignee
プロパティにこの特定のユーザーを含むすべてのアイテム オブジェクトを参照します。
これにより、Item コレクションをクエリして、特定のユーザーに割り当てられたすべてのアイテムを取得できるようになります。
逆の関係をクエリするには、Linq は使用できません。 代わりに、string 述語を渡します。 次の例では、「oscirator」という単語を含むアイテムを持つすべてのユーザーを検索する方法を示しています。
var oscillatorAssignees = realm.All<User>() .Filter("Items.Text CONTAINS 'oscillator'").ToList(); foreach (User u in oscillatorAssignees) { Console.WriteLine(u.Name); }
概要
関係は、オブジェクトが同じまたは別のオブジェクトタイプの他のオブジェクトを参照できるようにするオブジェクト プロパティです。
関係は直接参照です。 結合のタイプを記述せずに、関係プロパティを介して関連オブジェクトに直接アクセスできます。
Realm は 1 対多、対多、および逆の関係をサポートしています。