筛选和排序数据 - .NET SDK
要对域中的数据进行查询、过滤和排序,请使用 Realm 查询引擎。有两种方法可以通过 .NET SDK 使用查询引擎:
您应该尽可能使用 LINQ 语法进行查询,因为它符合 .NET 约定。
注意
关于本页中的示例
本页中的示例使用了一个任务列表应用的简单数据集。两种 Realm 对象类型分别是 Project
和 Task
。Task
具有名称、受让人名称和已完成标志。其中还有一个任意的优先级数字(数值越高表示越重要)以及处理所花费的分钟数。Project
具有零个或多个 Tasks
。
请参阅 Project
和 Task
这两个类的模式,如下所示:
public partial class Items : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } = ObjectId.GenerateNewId(); public string Name { get; set; } public string Assignee { get; set; } public bool IsComplete { get; set; } public int Priority { get; set; } public int ProgressMinutes { get; set; } } public partial class Project : IRealmObject { [ ] [ ] public ObjectId ID { get; set; } = ObjectId.GenerateNewId(); public string Name { get; set; } public IList<Items> Items { get; } }
使用 LINQ 查询
Realm 的查询引擎实现了标准 LINQ 语法。
有几种操作符可以使用 LINQ 过滤 Realm collection。过滤器的工作方式是对所过滤的集合中的每个对象计算操作符表达式。如果表达式解析为 true
,Realm 会将该对象包含在结果集合中。
表达式由以下任一内容组成:
当前正在求值的对象的某个属性的名称。
操作符
Realm 使用的任何类型的值(字符串、日期、数字、布尔值等)
注意
Realm .NET SDK 目前并不支持所有 LINQ 操作符。 有关这些不支持的操作符的列表,请参阅不支持的 LINQ 操作符部分。
比较操作符。
价值比较
Operator | 说明 |
---|---|
== | 如果左侧表达式等于右侧表达式,则计算结果为 true 。 |
> | 如果左侧的数值或日期表达式大于右侧的数值或日期表达式,则计算结果为 true 。对于日期,如果左侧日期晚于右侧日期,则计算结果为 true 。 |
>= | 如果左侧数值或日期表达式大于或等于右侧数值或日期表达式,则计算结果为 true 。对于日期,如果左侧日期晚于或等于右侧日期,则计算结果为 true 。 |
< | 如果左侧数值或日期表达式小于右侧数值或日期表达式,则计算结果为 true 。对于日期,如果左侧日期早于右侧日期,则计算结果为 true 。 |
<= | 如果左侧数值表达式小于或等于右侧数值表达式,则计算结果为 true 。对于日期,如果左侧日期早于或等于右侧日期,则计算结果为 true 。 |
!= | 如果左侧表达式不等于右侧表达式,则计算结果为 true 。 |
例子
以下示例使用查询引擎的比较运算符执行以下操作:
通过将
priority
属性值与阈值数字进行比较来查找高优先级任务,而高于该阈值的优先级可视为高优先级。通过查看
progressMinutes
属性是否在特定范围内来查找刚刚启动或短时间运行的任务。通过查找
assignee
属性等于null
的任务来查找未分配的任务。通过查看
assignee
属性是否在名称列表中来查找分配给团队成员 Ali 或 Jamie 的任务。
var highPri = items.Where(i => i.Priority > 5); var quickItems = items.Where(i => i.ProgressMinutes >= 1 && i.ProgressMinutes < 15); var unassignedItems = items.Where(i => i.Assignee == null); var AliOrJamieItems = items.Where(i => i.Assignee == "Ali" || i.Assignee == "Jamie");
逻辑操作符
您可以使用下表列出的逻辑操作符制作复合谓词:
Operator | 说明 |
---|---|
&& | 如果左侧和右侧表达式的值均为 true ,则计算结果为 true : |
! | 对给定表达式的结果予以否定。 |
|| | 如果任一表达式返回 true ,则计算结果为 true 。 |
例子
我们可以使用查询语言的逻辑运算符来查找 Ali 已完成的所有任务。也就是说,我们会查找 assignee
属性值等于“Ali”且 isComplete
属性值为 true
的所有任务:
var completedItemsForAli = items .Where(i => i.Assignee == "Ali" && i.IsComplete);
字符串操作符
您可以使用下表中列出的字符串操作符比较字符串值。类似正则表达式的通配符让搜索变得更加灵活。
Operator | 说明 |
---|---|
StartsWith | 如果左侧字符串表达式以右侧字符串表达式开头,则计算结果为 true 。这与 contains 类似,但仅当在右侧字符串表达式的最末尾找到左侧字符串表达式时才匹配。 |
EndsWith | 如果左侧字符串表达式以右侧字符串表达式结尾,则计算结果为 true 。这与 contains 类似,但仅当在右侧字符串表达式的最末尾找到左侧字符串表达式时才匹配。 |
Like | 如果左侧字符串表达式与右侧字符串通配符字符串表达式匹配,则计算结果为
例如,通配符字符串“d?g”匹配“dog”、“dig”和“dug”,但不匹配“ding”、“dg”或“a dog”。 |
Equals | 如果左侧字符串在字典顺序上等于右侧字符串,则计算结果为 true 。 |
Contains | 如果在左侧字符串表达式中的任意位置找到右侧字符串表达式,则计算结果为 true 。 |
string.IsNullOrEmpty | 如果左侧字符串表达式为 null 或空,则计算结果为 true 。 请注意, IsNullOrEmpty() 是string 上的静态方法。 |
例子
以下示例使用查询引擎的字符串操作符来查找任务:
// Note: In each of the following examples, you can replace the // Where() method with First(), FirstOrDefault(), // Single(), SingleOrDefault(), // Last(), or LastOrDefault(). // Get all items where the Assignee's name starts with "E" or "e" var ItemssStartWithE = items.Where(i => i.Assignee.StartsWith("E", StringComparison.OrdinalIgnoreCase)); // Get all items where the Assignee's name ends wth "is" // (lower case only) var endsWith = items.Where(t => t.Assignee.EndsWith("is", StringComparison.Ordinal)); // Get all items where the Assignee's name contains the // letters "ami" in any casing var itemsContains = items.Where(i => i.Assignee.Contains("ami", StringComparison.OrdinalIgnoreCase)); // Get all items that have no assignee var null_or_empty = items.Where(i => string.IsNullOrEmpty(i.Assignee));
重要
案例比较
计算字符串时,除 Like
之外的所有函数中的第二个参数都必须是 StringComparison.OrdinalIgnoreCase
或 StringComparison.Ordinal
。对于 Like()
方法,第二个参数是布尔值(其中“true”表示“区分大小写”)。
全文本搜索
您可以使用 LINQ查询具有全文搜索索引(FTS) 的属性。 要查询这些属性,请使用QueryMethods.FullTextSearch 。 以下示例查询Person.Biography
字段:
// Find all people with "scientist" and "Nobel" in their biography var scientists = realm.All<Person>() .Where(p => QueryMethods.FullTextSearch(p.Biography, "scientist Nobel")); // Find all people with "scientist" in their biography, but not "physics" var scientistsButNotPhysicists = realm.All<Person>() .Where(p => QueryMethods.FullTextSearch(p.Biography, "scientist -physics"));
不支持的 LINQ 操作符
Realm .NET SDK 目前不支持以下 LINQ 操作符:
category | 不支持的运算符 |
---|---|
Concatenation |
|
Grouping |
|
Partitioning |
|
Projection |
|
Sets |
|
使用 Realm 查询语言进行查询
您还可以使用 Realm Query Language (RQL) 来查询域。RQL 是一种基于字符串的查询语言,用于访问查询引擎。使用 RQL 时,需要使用 Filter() 方法:
var elvisProjects = projects.Filter("Items.Assignee == $0", "Elvis");
聚合操作符
聚合操作符遍历集合并将其简化为单个值。 请注意,聚合使用Filter()方法,该方法可用于创建 LINQ提供商当前不支持的更复杂的查询。 除筛选外, Filter()
还支持 SORT 和 DISTINCT 子句。
有关可用聚合操作符的更多信息,请参阅 Realm 查询语言聚合操作符参考。
以下示例显示了聚合数据的不同方法:
// Get all projects with an average Item priorty > 5: var avgPriority = projects.Filter( "Items.@avg.Priority > $0", 5); // Get all projects where all Items are high-priority: var highPriProjects = projects.Filter( "Items.@min.Priority > $0", 5); // Get all projects with long-running Items: var longRunningProjects = projects.Filter( "Items.@sum.ProgressMinutes > $0", 100);
全文本搜索
您可以使用 RQL 查询带有全文搜索索引 (FTS) 的属性。要查询这些属性,请使用 TEXT
操作符。 以下示例查询Person.Biography
字段:
// Find all people with "scientist" and "Nobel" in their biography var filteredScientists = realm.All<Person>() .Filter("Biography TEXT $0", "scientist Nobel"); // Find all people with "scientist" in their biography, but not "physics" var filteredScientistsButNotPhysicists = realm.All<Person>() .Filter("Biography TEXT $0", "scientist -physics");
对查询结果进行排序
排序操作允许您配置 Realm 返回查询对象的顺序。您可以根据结果集合中对象的一个或多个属性进行排序。
仅当结果已进行排序时,Realm 才能保证结果顺序一致。
例子
以下代码按名称倒序排列项目(即 “降序”)。
var projectsSorted = projects.OrderByDescending(p => p.Name);