Realm C# - LINQ用于空集合

时间:2017-04-13 16:11:34

标签: c# xamarin realm

我已经在XLrin的PCL中实现了领域。这样可以正常工作(正在存储和检索数据)。

现在,我正在构建越来越多的功能,我遇到了无法查询空集合的方法。

由于模型绑定,我需要返回IRealmCollection<Customer>,因此我无法枚举,然后过滤没有blogentries的项目。

我知道如何才能在IQueryable上实现这一目标吗?

我试过

 var realm = Realm.GetInstance();
 var customers = realm.All<Customer>();
 // errors out - only Realm-managed props can be used
 customers = customers.Where(x => x.BlogEntries.Count > 0));  
 // errors out - Any() is not supported
 customers = customers.Where(x => x.BlogEntries.Any()); 
 // errors out - Datatype mismatch in comparison
 customers = customers.Where(x => x.BlogEntries != null); 
 // errors out - Datatype mismatch in comparison
 customers = customers.Where(x => x.BlogEntries == default(IList<BlogEntries>));  

1 个答案:

答案 0 :(得分:0)

不幸的是,Realm Xamarin 1.2.0不支持。您可以做的是实施一个穷人的收集通知来解决这个问题:

public class MyViewModel
{
    private IRealmCollection<BlogEntry> _blogEntries;
    private IEnumerable<Customer> _customers;

    public IEnumerable<Customer> Customers
    {
        get { return _customers; }
        set { Set(ref _customers, value); }
    }

    public MyViewModel
    {
        Customers = realm.All<Customer>()
                         .AsEnumerable()
                         .Where(c => !c.BlogEntries.Any())
                         .ToArray();

        _blogEntries = realm.All<BlogEntry>().AsRealmCollection();
        _blogEntries.CollectionChanged += (s, e) =>
        {
            var updatedCustomers = realm.All<Customer>()
                                        .AsEnumerable()
                                        .Where(c => !c.BlogEntries.Any())
                                        .ToArray();

            if (!IsEquivalent(updatedCustomers, Customers))
            {
                Customers = updatedCustomers;
            }
        };
    }

    private bool IsEquivalent(Customer[] a, Customer[] b)
    {
        if (a.Length != b.Length)
        {
            return false;
        }

        for (var i = 0; i < a.Length; i++)
        {
            if (!a[i].Equals(b[i]))
            {
                return false;
            }
        }

        return true;
    }
}

当我们调用ToArray()时,我们只会丢失收集更改通知,我们通过观察Realm中的博客条目集合并简单地检查是否有任何更新来实现它们。如果您愿意,可以扩展此解决方案并将其包装在INotifyCollectionChanged的自定义实现中并绑定到该解决方案。然后,您甚至可以应用一些语义来引发正确的集合更改事件(或者为每个更改选择一个简单的.Reset)。

要解决任何性能问题,在Realm集合上调用ToArray将不会实现对象&#39;属性,所以它相对便宜。唯一有点昂贵的操作是迭代所有Customer个对象并检查它们的BlogEntries列表。我的建议是尝试一下,看看它是否对你的用例表现满意。