Search code examples
c#xamarinrealmrealm-net

How to implement "get or create" query with Realm for Xamarin?


Consider the simple model:

public class Session : RealmObject
{
    [ObjectId]
    public string UserId { get; set; }
    public string Token { get; set; }
}

How to get the Session instance by ID or null if it doesn't exist?

var realm = Realm.GetInstance ();
var q = realm.All<Session> ().Where ((x) => x.UserId = "1");
// This won't work if no session is saved:
// var session = q.First ();
// and this won't either
// var session = q.FirstOrDefault ();
// And this is mmm... kind of strange but it's working :)
var session = q.Count() > 0 ? q.First() : null;

So, how it's supposed to be done by design?


Solution

  • What you would like to do is:

    var localSession = theRealm.All<Session>().FirstOrDefault((Session session) => session.UserId == "1");
    

    But FirstOrDefault/SingleOrDefault is not yet supported (as of 0.77.2)

    Any, First and Single are currently supported (Current Linq Support):

    If/Else on Any style:

    Session session = null;
    var sessions = theRealm.All<Session>().Where((Session localSession) => localSession.UserId == "1");
    if (!sessions.Any())
        theRealm.Write(() =>
        {
            session = new Session() { UserId = "1", Token = "SO" };
        });
    else
        session = sessions.First();
    D.WriteLine($"{session?.UserId}:{session?.Token}");
    

    Try/Catch on InvalidOperationException:

    Session localSession = null;
    try
    {
        localSession = theRealm.All<Session>().First((Session session) => session.UserId == "1");
    }
    catch (InvalidOperationException error) when (error.Message == "Sequence contains no matching element")
    {
        theRealm.Write(() =>
        {
            localSession = new Session() { UserId = "1", Token = "SO" };
        });
    }
    D.WriteLine($"{localSession?.UserId}:{localSession?.Token}");