Reputation: 880
I am using Realm .NET to store model objects in a realm database. I have an existing model object called Employee
with a single property:
public class Employee : RealmObject
{
public string Username { get; set; }
}
The Realm database already contains a few instances of this type.
I am now trying to add a new property to the object which should be annotated with the [PrimaryKey]
attribute. The desired new version of the object should look like this:
public class Employee : RealmObject
{
[PrimaryKey]
public string Id { get; set; }
public string Username { get; set; }
}
Since the new Id
property will not contain suitable values for the existing database objects, I am trying to use the migration feature in Realm to seed their values. The code to perform the Realm migration looks like so:
private void MigrateToSchemaVersionWithEmployeeIds(Migration migration)
{
var employees = migration.NewRealm.All<Employee>();
foreach (var employee in employees)
{
employee.Id = Guid.NewGuid().ToString();
}
}
When starting the app, the migration code is executed but when assigning to the Id
property, an Exception
is thrown:
System.InvalidOperationException: Once set, primary key properties may not be modified.
As a workaround, I have determined that you can first add the property without the [PrimaryKey]
attribute, have its values seeded in the migration code (no exception is thrown in this case), stop the app, add the [PrimaryKey]
attribute to the property, increase the schema version and relaunch the app. As this is no workable solution for when an app is already deployed in production, I am looking for a way to achieve this without having to use such a workaround.
How can a property with a [PrimaryKey]
attribute be added to an existing model object in Realm .NET?
Upvotes: 2
Views: 260
Reputation: 2186
That is unfortunately, not possible. As a workaround, you can map your Employee
class to a new table like:
[MapTo("Employee2")]
public class Employee : RealmObject
{
[PrimaryKey]
public string Id { get; set; }
public string Username { get; set; }
}
It will allow you to keep using it as Employee
for all intents and purposes, but in the database itself it will be persisted as Employee2
. Then in the migration block, you could do:
private void MigrateToSchemaVersionWithEmployeeIds(Migration migration)
{
var employees = migration.OldRealm.All("Employee");
foreach (var employee in employees)
{
var newEmployee = new Employee
{
Id = Guid.NewGuid().ToString(),
Name = employee.Name
};
migration.NewRealm.Add(newEmployee);
}
}
Upvotes: 1