C# 领域+;Xamarin表单更新查询

C# 领域+;Xamarin表单更新查询,c#,xamarin,xamarin.forms,realm,observablecollection,C#,Xamarin,Xamarin.forms,Realm,Observablecollection,我使用Realm+Xamarin表单来完成我认为最基本的操作:列表视图显示项目集合,搜索栏根据用户类型过滤结果 我有一个get-only集合属性用作列表视图的items源,最初是从一个领域查询填充的,它会随着数据的任何更改而自动更新,但是如果不添加一个集合并替换整个集合,我就不知道如何更新搜索文本 这是非常低效的——我假设这会触发集合和集合中每个项的一组notify changed事件侦听器的重新注册,并且通常会导致每个字母被点击时出现大量混乱 在过去,我用搜索方法创建了自己的包装可观察集合来处

我使用Realm+Xamarin表单来完成我认为最基本的操作:列表视图显示项目集合,搜索栏根据用户类型过滤结果

我有一个get-only集合属性用作列表视图的items源,最初是从一个领域查询填充的,它会随着数据的任何更改而自动更新,但是如果不添加一个集合并替换整个集合,我就不知道如何更新搜索文本

这是非常低效的——我假设这会触发集合和集合中每个项的一组notify changed事件侦听器的重新注册,并且通常会导致每个字母被点击时出现大量混乱


在过去,我用搜索方法创建了自己的包装可观察集合来处理这个问题,我想这也是一个选项,但是有没有办法用Realm来实现呢?也就是说,要在不重新创建整个集合的情况下更新查询,请使用某种方法重新运行原始查询?

更新:此技术不再有效

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

…它也不同于LINQ对对象的行为,每次迭代都会重新计算表达式,这意味着对条件两侧的更改都会影响结果。领域查询将在第一次运行时计算条件的右侧

当您构造一个包含基于非领域条件的
Where
参数的查询时,除非您再次更新/执行查询,否则当这些变量/参数发生更改时,查询结果不会更新

领域查询是活动的,因为它们将继续表示数据库的当前状态

因此,我要做的是创建一个过滤器类(
RealmObject
),然后如果您实例一个“过滤器对象”,将其保存到Realm,您可以将Linq的
Where
参数基于一个或多个“过滤器”属性。通过域更新此
RealmObject
过滤器。添加(filterObject,true)基于该对象的查询也会更新

领域查询是活动的,因为它们将继续表示数据库的当前状态

结果是快速过滤,在任何UI搜索例程中都非常有效

示例模型: 用一些测试数据填充一个领域 注:引用文本@

public class ARealmClass : RealmObject
{
    public int Key { get; set; }
    public string KeyString { get; set; }
}

public class ARealmClassFilter : RealmObject
{
    [PrimaryKey]
    public int Key { get; set; }
    public int FilterKeyBy { get; set; }
}
var realm = Realm.GetInstance();
var all = realm.All<ARealmClass>();
if (all.Count() == 0)
{
    realm.Write(() =>
    {
        for (int i = 0; i < 1000; i++)
        {
            var obj = new ARealmClass { Key = i, KeyString = i.ToString() };
            realm.Add(obj);
        }
    });
}
var realm = Realm.GetInstance();
var all = realm.All<ARealmClass>();
Console.WriteLine(all.Count());
var filterItem = new ARealmClassFilter { Key = 1, FilterKeyBy = 500 };
realm.Write(() =>
{
    realm.Add(filterItem);
});
var filtered = all.Where(_ => _.Key > filterItem.FilterKeyBy);
Console.WriteLine(filtered.Count());
realm.Write(() =>
{
    filterItem.FilterKeyBy = 750;
    realm.Add(filterItem, true);
});
Console.WriteLine(filtered.Count());
2017-04-24 11:53:20.376 ios_build_foo[24496:3239020] 1000
2017-04-24 11:53:20.423 ios_build_foo[24496:3239020] 499
2017-04-24 11:53:20.425 ios_build_foo[24496:3239020] 249