Как добавить свойства, аннотированные с помощью PrimaryKey, к существующим объектам модели RealmObject в Realm. NET? - PullRequest
1 голос
/ 21 апреля 2020

Я использую Realm. NET для хранения объектов модели в базе данных области. У меня есть существующий объект модели с именем Employee с одним свойством:

public class Employee : RealmObject
{
    public string Username { get; set; }
}

База данных Realm уже содержит несколько экземпляров этого типа.

Я сейчас пытаюсь добавить новый свойство объекта, которое должно быть аннотировано атрибутом [PrimaryKey]. Требуемая новая версия объекта должна выглядеть следующим образом:

public class Employee : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; }

    public string Username { get; set; }
}

Поскольку новое свойство Id не будет содержать подходящих значений для существующих объектов базы данных, я пытаюсь использовать функцию миграции в Realm для семена их ценностей. Код для выполнения миграции Realm выглядит следующим образом:

private void MigrateToSchemaVersionWithEmployeeIds(Migration migration)
{
    var employees = migration.NewRealm.All<Employee>();
    foreach (var employee in employees)
    {
        employee.Id = Guid.NewGuid().ToString();
    }
}

При запуске приложения выполняется код миграции, но при назначении свойству Id выдается Exception:

System.InvalidOperationException: Once set, primary key properties may not be modified.

В качестве обходного пути я определил, что вы можете сначала добавить свойство без атрибута [PrimaryKey], добавив его значения в код миграции (в этом случае исключение не выдается) остановите приложение, добавьте атрибут [PrimaryKey] в свойство, увеличьте версию схемы и перезапустите приложение. Поскольку это нереализуемое решение для случая, когда приложение уже развернуто в рабочей среде, я ищу способ достичь этого без использования такого обходного пути.

Как может быть свойство с атрибутом [PrimaryKey] добавлен к существующему объекту модели в Realm. NET?

1 Ответ

0 голосов
/ 06 мая 2020

К сожалению, это невозможно. В качестве обходного пути вы можете сопоставить свой класс Employee с новой таблицей, например:

[MapTo("Employee2")]
public class Employee : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; }

    public string Username { get; set; }
}

Это позволит вам продолжать использовать его как Employee для всех намерений и целей, но в самой базе данных. оно будет сохранено как Employee2. Затем в блоке миграции вы можете сделать:

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);
    }
}
...