Alterar um modelo de objetos - .NET SDK
Nesta página
Visão geral
Uma migração transforma um Realm existente e seus objetos de sua versão atual doRealm Schema para uma versão mais recente. Modelos de dados de aplicativos normalmente mudam ao longo do tempo para acomodar novos requisitos e recursos. As migrações oferecem a flexibilidade de atualizar automaticamente os dados do aplicação existente sempre que um aplicação cliente for atualizado para uma versão mais recente.
Considere o seguinte exemplo, no qual temos um RealmObject
chamado "Pessoa":
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public int Age { get; set; } }
Suponha que agora queremos dividir a propriedade FullName
em duas propriedades separadas, FirstName
e LastName
:
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } }
Nesse ponto, há uma incompatibilidade entre o modelo e todos os dados salvos, e uma exceção será lançada quando você tentar abrir o realm.
Versão do esquema
A versão do esquema identifica o estado de um Realm Schema em algum momento. O Realm controla a versão do esquema de cada realm e o usa para mapear os objetos em cada realm para o esquema correto.
As versões de esquema são inteiros que você pode incluir na configuração do território quando você abre um domínio. Se um aplicativo cliente não especificar um número de versão quando abrir um domínio, o domínio assumirá como padrão a versão 0
.
Importante
Incrementar versões monotonicamente
As migrações devem atualizar um realm para uma versão superior do esquema. O Realm irá gerar um erro se um aplicativo cliente abrir um realm com uma versão do esquema inferior à versão atual do realm ou se a versão do esquema especificada for igual à versão atual do realm, mas incluir esquemas de objetos diferentes.
Migrar um esquema
Os exemplos seguintes demonstram como adicionar, excluir e modificar propriedades em um esquema. Primeiro, faça a alteração necessária no esquema. Em seguida, crie uma função de migração correspondente para mover os dados do esquema original para o esquema atualizado.
Observação
Modificar Propriedades do Esquema de um Domínio Sincronizado
A página seguinte demonstra como modificar as propriedades do esquema de um domínio local. Saiba como modificar as propriedades do esquema de um domínio sincronizado.
Observação
Atualização de versões no Realm Open
Suponha que cada alteração de esquema neste exemplo ocorra após um aplicativo ter usado cada versão por algum tempo. Os novos números de versão do esquema só se aplicam quando você abre o reino com um esquema atualizado e especifica explicitamente o número da nova versão; portanto, para chegar à versão 3, primeiro você precisa abrir o aplicativo com as versões 1 e 2.
Um domínio usando esquema versão 1
tem um tipo de objeto Person
:
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public int Age { get; set; } }
Adicionar uma propriedade
O exemplo a seguir adiciona uma propriedade LastName
ao esquema de Pessoa original:
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } }
Excluir uma propriedade
O exemplo a seguir usa uma propriedade FullName
combinada em vez das propriedades FirstName
e LastName
separadas no esquema Person original:
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public int Age { get; set; } }
Modificar um tipo de propriedade ou renomear uma propriedade
O exemplo a seguir modifica a propriedade Age
no esquema Pessoa original , renomeando-a para Birthday
e alterando o tipo para DateTimeOffset
:
public partial class Person : IRealmObject { [ ] [ ] public ObjectId Id { get; set; } public string FullName { get; set; } public DateTimeOffset Birthday { get; set; } }
Funções de migração
Dica
Ignorar migração durante o desenvolvimento
Ao desenvolver ou depurar seu aplicativo, talvez você prefira excluir o domínio em vez de migrá-lo. Use o sinalizador ShouldDeleteIfMigrationNeeded para excluir o banco de dados automaticamente quando uma incompatibilidade de esquema exigir uma migração.
Nunca libere um aplicativo para produção com esta sinalização definida como true
.
Para migrar o Realm para estar em conformidade com o esquema Person
atualizado, defina a versão do esquema do realm como 4
e defina uma função de migração para definir o valor de FullName
com base nas propriedades FirstName
e LastName
existentes e nas valor de Birthday
baseado em Age
:
1 var config = new RealmConfiguration 2 { 3 SchemaVersion = 4, 4 MigrationCallback = (migration, oldSchemaVersion) => 5 { 6 var oldVersionPeople = migration.OldRealm.DynamicApi.All("Person"); 7 var newVersionPeople = migration.NewRealm.All<Person>(); 8 9 // Migrate Person objects 10 for (var i = 0; i < newVersionPeople.Count(); i++) 11 { 12 var oldVersionPerson = oldVersionPeople.ElementAt(i); 13 var newVersionPerson = newVersionPeople.ElementAt(i); 14 15 // Changes from version 1 to 2 (adding LastName) will 16 // occur automatically when Realm detects the change 17 18 // Migrate Person from version 2 to 3: 19 // Replace FirstName and LastName with FullName 20 // LastName doesn't exist in version 1 21 var firstName = oldVersionPerson.DynamicApi.Get<string>("FirstName"); 22 var lastName = oldVersionPerson.DynamicApi.Get<string>("LastName"); 23 24 if (oldSchemaVersion < 2) 25 { 26 newVersionPerson.FullName = firstName; 27 } 28 else if (oldSchemaVersion < 3) 29 { 30 newVersionPerson.FullName = $"{firstName} {lastName}"; 31 } 32 33 // Migrate Person from version 3 to 4: replace Age with Birthday 34 if (oldSchemaVersion < 4) 35 { 36 var birthYear = 37 DateTimeOffset.UtcNow.Year - oldVersionPerson.DynamicApi.Get<int>("Age"); 38 newVersionPerson.Birthday = 39 new DateTimeOffset(birthYear, 1, 1, 0, 0, 0, TimeSpan.Zero); 40 } 41 } 42 } 43 }; 44 var realm = Realm.GetInstance(config);