2017-09-24 37 views
0

该领域文档给出了一个使用人物对象和狗对象的反向链接示例。如果我把它扩展到包括猫,那么一个人可以有几只狗或猫走路,每只狗或猫可以由几个不同的人走路。查询具有多个反向链接的领域

public class Dog : RealmObject 
{ 
    public string Name { get; set; } 

    [Backlink(nameof(Person.Dogs))] 
    public IQueryable<Person> Walkers { get; } 
} 

public class Cat : RealmObject 
{ 
    public string Name { get; set; } 

    [Backlink(nameof(Person.Cats))] 
    public IQueryable<Person> Walkers { get; } 
} 

public class Person : RealmObject 
{ 
    //... other properties (name, age, address, etc.) 
    public IList<Dog> Dogs { get; } 
    public IList<Cat> Cats { get; } 
} 

使用反向让我得到谁遛狗菲多的人的名单...

var fidoWalkers = realm.All<Dog>().Where(d => d.Name == "Fido").FirstOrDefault().Walkers; 

我现在可以进一步扩大此查询找到谁住在大街菲的步行者或谁是30岁以下或其他......迄今为止都很棒。

现在我想要得到一个走狗Fido和猫咪Moggie的人的名单。在两个单独的声明中使用反向链接,我可以得到两个结果集,一个用于Fido步行者,一个用于Moggie步行者,但我不知道如何组合它们。无论是我能制定出一个查询,将让我这样做“很长的路要走轮”不使用反向链接,因为每当我尝试使用

...Where(P => p.Dogs.Contains(Fido))... 

我得到的“System.NotSupportedException:方法‘包含’被不支持“

有没有什么办法可以获得由狗和猫列表过滤的人列表?

回答

0

虽然有很多事情境界的.NET版本做得很好,也有在Linq支持限制,因此你不得不兑现懒惰通过LINQ to Objects,以便执行加载IRealmCollection到硬List(或阵列)投影,连接,IEqualityComparer比较等...这包括反向链接和基于RealmObject的IList属性。

必读Realm-dotnet文件:LINQ support in Realm Xamarin

可以添加执行Linq投影字符串列表属性的夫妇(宠物的名字,当然,假设他们是唯一键):

public class Person : RealmObject 
{ 
    //... other properties (name, age, address, etc.) 
    public IList<Dog> Dogs { get; } 
    public IList<Cat> Cats { get; } 

    public List<string> DogList => Dogs.ToList().Select(_ => _.Name).ToList(); 
    public List<string> CatList => Cats.ToList().Select(_ => _.Name).ToList(); 
} 

然后将您的人员查询转到列表并在物化字符串列表上使用Contains与RealmCollection属性。

var walkers = realm.All<Person>().ToList().Where(_ => _.CatList.Contains("Garfield") && _.DogList.Contains("Fido")); 
foreach (var walker in walkers) 
{ 
    Log.Debug(TAG, $"{walker}"); 
} 

您还可以创建两个查询,一个过滤狗的名字反向链接和猫为别的,物化在两个查询每个人的所有狗和猫的集合,通过自定义IEqualityComparer执行Distinct

一旦复制的对象出境界的成独立列表/阵列,几乎所有的LINQ的解决方案将工作...

这样做的缺点是被在内存中执行所有过滤所以你需要内存和CPU打你不能使用Realm的原生查询功能...

就个人而言,我会重新建模RealmObject的提供人走动物,因此动物是通用的,他们反过来提供链接特定的狗和猫提供专业化的对象。但那完全不知道你的最终目标......

+0

很好的答案谢谢你 - 现在我有了更好的理解。我的实际模型显然要复杂得多(实际上是一个缝纫模式对象的目录,每个模型对象都有多种服装类型,织物类型,类别和标签等),但是我会考虑改变模型结构与速度/记忆命中的实用性在内存列表上运行LINQ查询。需要更多实验...... – sparks

+0

@sparks没问题,我个人认为使用Realm时最佳内存/ CPU使用率所需的一件事是设计适合您应用使用模式的Realm模型的能力。当客户说模型可以*不*改变**期**时,我倾向于SQLite。当我们有从App使用的角度重新思考模型的自由时,Realm在性能,使用“实时”对象等方面可以是惊人的......但通常原始模型结束(高度)非规范化并且我们在服务器上创建一个数据映射来处理JSON序列化/反序列化...... – SushiHangover

+0

@sparks就'应用程序使用模式'而言,我看每页,屏幕,表,Activity,片段,UITableView等显示的内容...这是我的Realm模型的每个应用程序视图的开始。如果它没有显示在屏幕上,按API或同步/等使用的主键/隐藏键......我不包括它。在应用程序中显示数据之后,每种方法都是已知的,它变得“容易”;-)将所有这些小型模型片段建模成高度高性能的合并非规范化模型....更改模型的应用程序版本为通过Realm迁移处理。 – SushiHangover