Make Primary Key Required

cloud

#1

We use Guid.ToString() to create primary keys and our primary keys are annotated with [PrimaryKey].

We naively thought [PrimaryKey] followed the database convention that this also meant the primary key is not nullable.

We now know that Realm allows null primary keys where the primary key datatype is nullable. I’ve therefore added the annotation [Required] to our string primary keys but this throws the exception

The following changes cannot be made in additive-only schema mode:- Property ‘Customer.CustomerId’ has been made required

and so on for all our primary keys.

We have quite a number of users running their businesses on our software so we really can’t ignore this or start again.

Is there a workaround for adding [Required] to existing primary keys?


#2

Unfortunately, that is not possible with the current design. The problem is that an old client that doesn’t have the [Required] annotation may insert an object with null for primary key, which will then result in undefined behavior for new clients.


#3

Thank you for the response @nirinchev even though it was negative I am hopeful we can keep moving forward.

Can we use [MapTo] in combination with [PrimaryKey], initialise the primary key with a non null value and trap attempts to set it to null?

internal class Customer : RealmObject
{
    [PrimaryKey]
    [MapTo(nameof(CustomerId))]
    private string _CustomerId { get; set; } = Guid.NewGuid().ToString();
    public string CustomerId
    {
        get { return _CustomerId; }
        set => _CustomerId = value ?? throw new Exception("CustomierId cannot be null");
    }

It builds without error, but I’ve learned that doesn’t always mean it is valid.


#4

But do you ever need to set the primary key to something different from the original guid? I would go one step further and just make the setter private to prevent anyone from setting it. That is, of course, unless you have a legitimate need to set it, e.g. you deserialize objects from json responses, in which case your proposed solution will work fine.


#5

Yes we do need to change the primary key after object creation. Thanks for confirming this will work. That’s very encouraging.