How to return an unmanaged object?


#1
public static Person GetPerson()
{
    Person p;
    using (Realm realm = RealmService.GetRealm()) realm.Write(() =>
    {
        Person r = new Person();
        r.Email = "[email protected]";
        realm.Add(r, update: true);
    });
    using (Realm realm = RealmService.GetRealm())
    {
        Person r = realm.Find<Person>("[email protected]");
        p = r;
    }
    System.Diagnostics.Debug.WriteLine(p.Email);
    return p;
}

p.Email throws RealmClosedException.

How do I return a person object?


#2

You need to create new Person() and map the managed object’s values over.


#3

It throws this exception because you’ve closed the Realm that this Person belongs to. Remember that Realm is not an ORM, but rather a live-object database. When accessing object properties, it fetches the values directly from the database, so when the Realm is closed, the Person object is no longer connected to the database. You can either not dispose of the Realm (but then risk getting into threading exceptions due to your method being static), or you can copy the data from the live object into an unmanaged one, e.g.:

var result = new Person
{
    Email = p.Email
}

Also, not sure what’s going on there, but there’s no reason to add the object to Realm and then fetch it again to return it.


#4

I wrote that as demo code to illustrate the issue. I understand Realm is not an ORM, but in a complex business application you usually don’t want changes immediately persisted so you can’t use ‘live’ objects in the presentation layer.

We had ported our application to Realm by creating a layer in our app that mapped realm objects to unmanaged objects, but it gets really scary with lots of complex objects and relationships. Oh well, it is what it is,

EDIT: Just thinking a bit more … is there a generic way to map properties of a managed object to an unmanaged object? Something along the lines of

Person unmanagedPerson = new Person();
for(i==0; i==p.Properties.Count, i++)
    unManagedPerson.Property[i] = p.Property[i];

#5

You can use AutoMapper to do that for you. Or expose Object.MemberwiseClone as a public method. Be aware though that you’ll likely have to ensure to handle relationships to avoid extracting your entire database in memory.


#6

Got it … be smart about what I return. Thanks @nirinchev.