2017-09-24 41 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