The left-hand side of the Equal operator must be a direct access to a persisted property in Realm


#1

Following the Realm docs for custom setters I have

public class Person : RealmObject
{
    [PrimaryKey]
    private string Email_ { get; set; }

    // Validating version of persistent Email_ property
    public string Email
    {
        get { return Email_; }
        set
        {
            if (!value.Contains("@")) throw new Exception("Invalid email address");
            Email_ = value;
        }
    }
}

this line
bool found = realm.All<Person>().Any(e => e.Email == "[email protected]");
returns the error

The left-hand side of the Equal operator must be a direct access to a persisted property in Realm.
Unable to process e.Email.

Where have I gone wrong?


#2

You can’t query non-persisted members. In this case, there’s no property called Email stored in Realm and there’s no way for us to deduct the correct name of the property (Email_). One thing you could try is decorate Email_ with [MapTo] attribute:

[PrimaryKey]
[MapTo("Email")]
private string Email_ { get; set; }

I haven’t tested it but in theory, it should allow you to perform the query. Alternatively, you’ll need to expose Email_ for query purposes (e.g. by making only the setter private to ensure sets go through the validation logic).


#3

Thanks @nirinchev. Making the getter public and setter private returned the same error, but combining your suggestions did the trick:

public class Person : RealmObject
{
    [PrimaryKey]
    [MapTo("Email")]
    public string Email_ { get; private set; }

    // Validating version of persistent Email_ property
    public string Email
    {
        get { return Email_; }
        set
        {
            if (!value.Contains("@")) throw new Exception("Invalid email address");
            Email_ = value;
        }
    }
}

#4

By making the getter public, I meant you’d need to query by the Email_ property like:

realm.All<Person>().Any(e => e.Email_ == "[email protected]")

If you use [MapTo], you shouldn’t need to make the getter public (as nobody is going to access the property anyway).


#5

Thanks again @nirinchev. This works too:

public class Person : RealmObject
{
    [PrimaryKey]
    [MapTo("Email")]
    private string Email_ { get; set; }

    // Validating version of persistent Email_ property
    public string Email
    {
        get { return Email_; }
        set
        {
            if (!value.Contains("@")) throw new Exception("Invalid email address");
            Email_ = value;
        }
    }
}

#6

I also got this error! When I use the method: user.GetPermissionChanges(ManagementObjectStatus.Error);
It shows me: System.NotSupportedException: The left-hand side of the NotEqual operator must be a direct access to a persisted property in Realm.Unable to process ‘p.StatusCode’.

I was confused… It’s a system method!
My realm .net version is 3.0.0, I think maybe the LINQ provider cannot read the MapTo attribute, It still uses the property name not the alias name to query the data…

Please take a look…


#7

Looks like a regression I introduced in 3.0.0. I’ll look into fixing it next week. For now, you can revert back to 2.2.0.