在部署Realm后,是否可以在ViewModel中使用RealmObject?

时间:2018-02-03 17:44:17

标签: c# .net mvvm uwp realm

我正在考虑在我的UWP应用程序中从SQLite切换到Realm,因为Realm似乎相当容易设置,但是我遇到了一些限制,到目前为止对我来说是一个限制因素,最重要的是显然,在处理用于检索它们的Realm实例后,您无法使用realm对象。所以我想知道如何加载数据以引入ViewModel,就像加载Realm实例将要消失的数据项一样。

以下是一个非常基本的ViewModel示例:

public class MyViewModel : ViewModelBase // Assume this has INotifyPropertyChanged setup
{
    private IEnumerable<MyItem> _Items;

    public IEnumerable<MyItem> Items
    {
        get => _Items;
        private set => Set(nameof(Items), ref _Items, value);
    }

    public async Task LoadDataAsync()
    {
        using (Realm realm = await Realm.GetInstanceAsync())
        {
            Items = realm.All<MyItem>().ToArray();
        }
    }
}

假设MyItem是一些示例模型,它继承自RealmObject

现在,如果我使用的是SQLite,那么我就没有任何问题,因为一旦从数据库中检索到,每个模型实例都是一个独立的对象,我只能存储在我的ViewModel中。相反,从RealObject继承的类链接到其原始Realm实例,因此如果我尝试在源Realm实例之后使用它们(即读取其中一个属性)处置完毕,一切都崩溃了(我得到了一个很好的Exception)。

明显的解决方法是为每个模型保留两个类:一个映射到Realm数据库,另一个映射到独立对象。但这有一些缺点:

  • 班级数量的两倍
  • 将每个实例复制到独立类的其他工作(和内存浪费)
  • 这似乎错了,我的意思是,来吧

另一种可能性是保持一个永远不会关闭的Realm对象的单例实例,但听起来也不是一个好主意(并且在使用多个线程时它也会有问题,所以它肯定是不是一个有效的解决方案。)

我已经看到Realm库的Java版本有一些“getRawObject”方法(或类似的东西),它允许你获得RealmObject的独立副本,但是,我想这实际上是创建模型实例的副本,因此听起来也不好。

我的问题是:

  

有没有办法获得SQLite的相同灵活性,一旦加载,你可以在任何你想要的地方传递模型(包括到其他线程),在ViewModels中使用它们,然后最终编辑它们并传递它们回到数据库以在磁盘上更新它们?

加分点:作为另一个例子,考虑一个从Realm数据库加载一些项目并将它们返回给用户的库。一旦加载,这些对象将是只读的,这意味着即使它们以某种方式被修改,它们也不会在数据库本身上被更改。我当前的解决方案是再次将每个加载的模型复制到另一个不继承自RealmObject的类中,但正如我所说,这根本不可扩展(想象一个包含数十个模型的大型项目,这是不可能的这样做。)

1 个答案:

答案 0 :(得分:0)

在.NET中,只有在以某种方式创建它的副本时,似乎才可以从Realm中分离托管的RealmObject。

请参阅https://stackoverflow.com/a/38061292/2413303

public Contact ToStandalone()
{
    return new Contact()
    {
        companyName = this.companyName,
        dateAdded = this.dateAdded,
        fullName = this.fullName,
        gender = this.gender,
        website = this.website
    };
}

从技术上讲,它不必是一个不同的类,但需要使用new创建。

至于必须制作副本 - 嗯,这也是你一直用SQLite做的事情。