Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

关系 - .NET SDK

在此页面上

  • 定义关系属性
  • 对一关系
  • 对多关系
  • 反向关系
  • 总结

Realm 允许您定义应用中对象类型之间的显式关系。关系是一种对象属性,该属性引用的是另一个 Realm 对象,而不是一种原始数据类型。您可以通过将属性类型设置为另一个 Realm 类来定义关系。

重要

继承

所有Realm对象都继承自 IRealmObjectIEmbeddedObjectIAsymmetricObject接口,并且必须声明为 partial类。

在早于10.18.0的 .NET SDK 版本中, 派生自RealmObjectEmbeddedObjectAsymmetricObject基类的对象。 这种 Realm 模型定义方法仍然受支持,但不包括可空性注解等新功能。 在未来的 SDK 版本中,基类将被弃用。 您编写的任何新类都应使用接口,并应考虑迁移现有类。

关系是对 Realm 中其他对象的直接引用,这意味着您不需要像在关系数据库中那样使用桥接表或显式联接来定义关系。 相反,您可以通过读取和写入定义关系的属性来访问相关对象。 Realm 会延迟执行读取操作,因此查询关系与读取常规属性一样有效。

提示

另请参阅:

或者,您可以在 App Services 应用程序中定义关系

提示

另请参阅:

对象之间主要有三种关系:

对一关系是指一个对象以特定方式与不超过一个其他对象相关。您可以通过指定属性(其中该类型是相关 Realm 对象类型)来为对象模式中的对象类型定义对一关系。

例子

应用程序可以使用以下对象模式,通过将其包含在其dog属性中来指示 Person 可能拥有也可能不拥有单个 Dog:

public partial class Person : IRealmObject
{
[PrimaryKey]
[MapTo("_id")]
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
{
[PrimaryKey]
[MapTo("_id")]
public ObjectId Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Breed { get; set; } = String.Empty;
}

若要查询直接关系,可以使用 LINQ 语法。 有关如何查询一对一关系,请参阅以下示例:

var fidosPerson = realm.All<Person>().FirstOrDefault(p => p.Dog == dog);

对多关系是指一个对象以特定方式与多个对象相关。您可以通过指定一个属性来定义对象类型的对多关系,其类型为相关 Realm 对象类型的 IList<T>。仅使用一个 getter 定义 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"
});

例子

应用程序可以使用以下对象模式来指示一个 Person 可以拥有多只 Dog,方法是将它们包含在其 dog 属性中:

public partial class Person : IRealmObject
{
[PrimaryKey]
[MapTo("_id")]
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
{
[PrimaryKey]
[MapTo("_id")]
public ObjectId Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Breed { get; set; } = String.Empty;
}

要查看 Person 与 Dog 的对多关系,您可以查询 Person 并获取该人的 Dog:

var katieAndHerDogs = realm.All<Person>().
Where(p => p.Name == "Katie")
.FirstOrDefault();

反向关系将对象链接回在定义的对一或对多关系中引用该对象的任何其他对象。关系定义是单向的,因此必须在对象模型中明确将属性定义为反向关系。

例如,对多关系“a User has many Items”不会自动创建反向关系“Task belongs to User”。如果不在对象模型中指定反向关系,就需要运行单独的查询来查找分配给某个项目的用户。

要定义反向关系,请在对象模型中定义仅 getter 的IQueryable<T>属性,其中T是关系的源类型,然后使用 [Backlink(sourceProperty)] 属性注释此属性,其中 "sourceProperty" 是关系另一方的属性名称。 以下示例说明如何使用 "User has many Items" 场景执行此操作:

public partial class User : IRealmObject
{
[PrimaryKey]
[MapTo("_id")]
public ObjectId Id { get; set; } = ObjectId.GenerateNewId();
public string Name { get; set; }
[Backlink(nameof(Item.Assignee))]
public IQueryable<Item> Items { get; }
}
public partial class Item : IRealmObject
{
[PrimaryKey]
[MapTo("_id")]
public ObjectId Id { get; set; } = ObjectId.GenerateNewId();
public string Text { get; set; }
public User? Assignee { get; set; }
}

在此示例中,请注意:

  • 列项对象的 Assignee 属性是用户对象。

  • User 对象的Items属性反转关系并引用在其Assignee属性中包含此特定 User 的所有 Item 对象。

这样,我们就可以查询列项集合,获取分配给特定用户的所有列项。

要查询反向关系,您不能使用 Linq 命令。相反,您要传递字符串谓词。以下示例显示如何查找所有列项中包含“oscillator”一词的用户:

var oscillatorAssignees = realm.All<User>()
.Filter("Items.Text CONTAINS 'oscillator'").ToList();
foreach (User u in oscillatorAssignees)
{
Console.WriteLine(u.Name);
}
  • 关系是一种对象属性,其支持对象引用相同或不同对象类型的其他对象。

  • 关系是直接引用。您可以通过关系属性直接访问相关对象,而无需编写任何类型的联接。

  • Realm 支持对一、对多和反向关系。

后退

手动定义模式