查询领域有多个反向链接

时间:2017-09-24 19:35:53

标签: xamarin realm

Realm文档提供了使用person对象和dog对象的反向链接示例。如果我把它扩展到包括猫,那么一个人可以有几只狗或猫走路,每只狗或猫可以由几个不同的人走路。

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; }
}

使用反向链接让我得到一个遛狗Fido的人员名单......

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

我现在可以进一步扩展这个查询,找到居住在大街或30岁以下或其他什么的Fido的步行者......到目前为止很棒。

现在我想得到一个遛狗Fido和猫Moggie的人的名单。在两个单独的陈述中使用反向链接,我可以得到两个结果集,一个用于Fido步行者,一个用于Moggie步行者,但我不知道如何组合它们。我也不能找出一个可以让我这样做的查询,而且还有很长的路要走。不使用反向链接,因为每当我尝试使用

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

我得到了System.NotSupportedException:方法&#39;包含&#39;不受支持&#39;

有没有办法获得Dogs和Cats列表过滤的人员列表?

1 个答案:

答案 0 :(得分:0)

虽然RealNet的.Net版本有很多功能,但Linq支持存在限制,因此您不得不将延迟加载的IRealmCollection实现为硬List }(或数组)via LINQ to Objects以执行投影,连接,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();
}

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

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

您还可以创建两个查询,一个在狗的名称反向链接上过滤,另一个过滤猫,在两个查询中实现每个人的所有Dog和Cat集合,通过一个Distinct执行自定义IEqualityComparer

一旦将对象从Realm复制到独立的列表/数组中,几乎任何Linq解决方案都可以工作......

这样做的缺点是所有过滤都在内存中执行,因此您无法使用Realm的本机查询功能而占用内存和CPU;

就个人而言,我会重新模拟RealmObject以提供行走动物的人,因此动物是通用的,它们又提供了与特定狗和猫RealmObjects的链接,提供专业化。但这完全不知道你的最终目标......