primo luogo, ottenere json NUGET:
PM> Install-Package Newtonsoft.JSON
E, provate questo "hack":
deserializzare il modificato proprietàIsManaged
fa i trucchi.
public d DetachObject<d>(d Model) where d : RealmObject
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<d>(
Newtonsoft.Json.JsonConvert.SerializeObject(Model)
.Replace(",\"IsManaged\":true", ",\"IsManaged\":false")
);
}
.
Se di fronte rallentamento on JsonConvert:
Secondo source code , di proprietà della 'ismanaged' ha sologet
di accesso ereturn true
quando privata campo_realm
che è disponibile
Quindi, dobbiamo impostare il esempio di campo_realm
-null
fa i trucchi
public d DetachObject<d>(d Model) where d : RealmObject
{
typeof(RealmObject).GetField("_realm",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(Model, null);
return Model.IsManaged ? null : Model;
}
.
Otterrete vuoto RealmObject
corpo dopo Realm sono ora implementata stessa strategia LazyLoad
record verso il basso dal vivo esempio regnoRealmObject
e (disattivare) in oggettoReflection
. E ripristinare i valori registrati suRealmObject
. Con anche tutti gliIList
s interni.
public d DetachObject<d>(d Model) where d : RealmObject
{
return (d)DetachObjectInternal(Model);
}
private object DetachObjectInternal(object Model)
{
//Record down properties and fields on RealmObject
var Properties = Model.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
.Where(x => x.Name != "ObjectSchema" && x.Name != "Realm" && x.Name != "IsValid" && x.Name != "IsManaged" && x.Name != "IsDefault")
.Select(x =>(x.PropertyType.Name == "IList`1")? ("-" + x.Name, x.GetValue(Model)) : (x.Name, x.GetValue(Model))).ToList();
var Fields = Model.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
.Select(x => (x.Name, x.GetValue(Model))).ToList();
//Unbind realm instance from object
typeof(RealmObject).GetField("_realm", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(Model, null);
//Set back the properties and fields into RealmObject
foreach (var field in Fields)
{
Model.GetType().GetField(field.Item1, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).SetValue(Model, field.Item2);
}
foreach (var property in Properties.OrderByDescending(x=>x.Item1[0]).ToList())
{
if (property.Item1[0] == '-')
{
int count = (int)property.Item2.GetType().GetMethod("get_Count").Invoke(property.Item2, null);
if (count > 0)
{
if (property.Item2.GetType().GenericTypeArguments[0].BaseType.Name == "RealmObject")
{
for (int i = 0; i < count; i++)
{
var seter = property.Item2.GetType().GetMethod("set_Item");
var geter = property.Item2.GetType().GetMethod("get_Item");
property.Item2.GetType().GetField("_realm", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public).SetValue(property.Item2, null);
DetachObjectInternal(geter.Invoke(property.Item2, new object[] { i }));
}
}
}
}
else
{
Model.GetType().GetProperty(property.Item1, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).SetValue(Model, property.Item2);
}
}
return Model;
}
.
per la lista del RealmObject
, Usare Select():
DBs.All<MyRealmObject>().ToList().Select(t => DBs.DetachObject(t)).ToList();
.
(Java) non avete bisogno di questo se sei in java:
Forse un giorno, questa funzionalità verrà a.NET Realm
Realm.copyFromRealm();
#xamarin # C# #Realm #RealmObject #detach #managed #IsManaged #copyFromRealm
Nella mia app, ho bisogno di sapere ogni proprietà di ogni oggetto che viene aggiornato dal UI in modo che io possa registrarlo su una tabella per motivi di sincronizzazione. Quindi ho davvero bisogno di un DataLayer con logica per questo. Se stavo creando un'app che utilizzava solo dati locali, avrei pensato che avere tutti gli oggetti "live" o "gestiti" avrebbe senso. – J3RM