我正在考虑在我的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
的类中,但正如我所说,这根本不可扩展(想象一个包含数十个模型的大型项目,这是不可能的这样做。)
答案 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做的事情。