0

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?

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
rudyryk
  • 3,695
  • 2
  • 26
  • 33

2 Answers2

2

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}");
SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • `try / catch` approach seems quite natural to me as far as `FirstOrDefault` is not supported yet :) But I'm not sure is it a good practice in .NET programming? – rudyryk Sep 02 '16 at 20:40
  • 1
    The overhead of a try/catch can be an issue if you are throwing and are doing this a lot, but assuming once you have a "session" for the user, say once per App run, there is no over head since you are never unwinding the stack since your session exists.... Just depends upon your preference since this really is a stop gap till better ling support is available. – SushiHangover Sep 02 '16 at 20:53
2

Update Support for var localSession = theRealm.All<Session>().FirstOrDefault(session => session.UserId == "1"); has shipped in version 0.78.0 onwards.

Original

I am now working on the relevant Realm issue.

Please add comments on there for specific scenarios you would like supported.

Note that we also now have a Nightly feed if you want to try something ahead of an official NuGet release.

Andy Dent
  • 17,578
  • 6
  • 88
  • 115