Построить правильную область Подзапрос - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть 2 таблицы: Quest и HistoryItem;

Упрощенный квест:

public class Quest : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();

    public string Name { get; set; }

    public int MaxRepeats { get; set; }        
}

Упрощенный HistoryIyem:

public class HistoryItem : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();

    public DateTimeOffset DoneTime { get; set; }

    public Quest Quest { get; set; }
}

Как правильно написать подзапрос области для отображениявсе квесты, которые были завершены меньше, чем questItem.MaxRepeats?В случае, если каждый законченный квест будет добавлен в новое поле HistoryItem.Quest;

Как я понял, это должно быть что-то вроде:

_db.Realm.All<Quest>().Filter($"SUBQUERY(HistoryItem, $hi, $hi.Quest).@count > $hi.Quest.MaxRepeats");

, но по некоторым причинам он не фильтруется правильно =(

Realms.Exceptions.RealmException: 'SUBQUERY (HistoryItem, $ hi, $ hi.Quest). @ Count> $ hi.Quest.MaxRepeats: 1: 8 (8): неверный предикат.'

Этот подзапрос написан на основе документации пример:

realm.All<Person>().Filter("SUBQUERY(Dogs, $dog, $dog.Vaccinated == false).@count > 3");
// find all people who have more than 3 unvaccinated dogs.

Возможно, здесь будет некоторая полезная информация NSPredicateCheatsheet илиздесь Примеры использования фильтра

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Привет, Эндрю Вы можете сделать это легко (но немного грязно) с помощью LINQ, набрав

_db.Realm.All<Quest>().Where(p=>_db.Realm.All<HistoryItem>().Count(u=>U.Quest==p)<p.MaxRepeats)

Как вы видите, мы должны сначала получить HistoryItem.Count.

0 голосов
/ 17 декабря 2018

Вам необходимо установить связь между Quest и HistoryItem:

public class Quest : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();

    public string Name { get; set; }

    public int MaxRepeats { get; set; } 

    [Backlink(nameof(HistoryItem.Quest))]
    public IQueryable<HistoryItem> HistoryItems{ get; }       
}

public class HistoryItem : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();

    public DateTimeOffset DoneTime { get; set; }

    public Quest Quest { get; set; }
}

Тогда вы можете использовать LINQ для запроса квестов:

_db.Realm.All<Quest>().Filter("HistoryItems.@count <= MaxRepeats");
...