Во-первых, получить json NUGET:
PM> Install-Package Newtonsoft.Json
И, попробуйте это "взломать":
Deserialize модифицированныйIsManaged
свойство делает трюки.
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")
);
}
.
Если вы сталкиваетесь медленно вниз на JsonConvert:
Согласно source code , свойство 'IsManaged' имеет толькоget
аксессор иreturn true
, когда частное поле_realm
который доступен
Итак, мы должны установить Экземпляр поля_realm
вnull
делает трюки
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;
}
.
вы получите пустой RealmObject
тело после того, как Realm теперь реализованы же стратегию LazyLoad
Запись вниз живойRealmObject
и (деактивировать) экземпляр области действия в объекте с помощьюReflection
. И установите записанные значения наRealmObject
. С обработаны всеIList
s внутри тоже.
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;
}
.
Для Список в RealmObject
, используя Select():
DBs.All<MyRealmObject>().ToList().Select(t => DBs.DetachObject(t)).ToList();
.
(Java) Вы не нуждаетесь в этом, если вы находитесь в Java:
Может быть, когда-нибудь, эта функция придет.NET Realm
Realm.copyFromRealm();
#xamarin # C# #Realm #RealmObject #detach #managed #IsManaged #copyFromRealm
В моем приложении, мне нужно знать все свойства каждого объекта, который обновляется с помощью пользовательского интерфейса так что я могу записать его в таблицу по причинам синхронизации. Поэтому мне действительно нужен DataLayer с логикой для этого. Если бы я создавал приложение, в котором использовались только локальные данные, я бы подумал, что иметь все объекты «живые» или «управляемые» будут иметь смысл. – J3RM