⚠️ Links are currently not supported in Isar v4
Links
Os links permitem que você expresse relacionamentos entre objetos, como o autor de um comentário (Usuário). Você pode modelar relacionamentos 1:1
, 1:n
e n:n
com links Isar. Usar links é menos ergonômico do que usar objetos incorporados e você deve usar objetos incorporados sempre que possível.
Pense no link como uma tabela separada que contém a relação. É semelhante às relações SQL, mas possui um conjunto de recursos e API diferentes.
IsarLink
IsarLink<T>
pode conter nenhum ou um objeto relacionado e pode ser usado para expressar um relacionamento de um para um. IsarLink
tem uma única propriedade chamada value
que contém o objeto vinculado. Os links são preguiçosos, então você precisa dizer ao IsarLink
para carregar ou salvar o valor
explicitamente. Você pode fazer isso chamando linkProperty.load()
e linkProperty.save()
.
Dica
A propriedade id das coleções de origem e destino de um link não deve ser final.
Para destinos não Web, os links são carregados automaticamente quando você os usa pela primeira vez. Vamos começar adicionando um IsarLink a uma coleção:
@collection
class Teacher {
late int id;
late String subject;
}
@collection
class Student {
late int id;
late String name;
final teacher = IsarLink<Teacher>();
}
Definimos um vínculo entre teachers e students. Cada student pode ter exatamente um teacher neste exemplo.
Primeiro, criamos o teacher e o atribuímos a um student. Temos que fazer o .put()
do teacher e salvar o link manualmente.
final mathTeacher = Teacher()..subject = 'Math';
final linda = Student()
..name = 'Linda'
..teacher.value = mathTeacher;
await isar.writeAsync((isar) async {
await isar.students.put(linda);
await isar.teachers.put(mathTeacher);
await linda.teacher.save();
});
Agora podemos usar o link:
final linda = await isar.students.where().nameEqualTo('Linda').findFirst();
final teacher = linda.teacher.value; // > Teacher(subject: 'Math')
Vamos tentar a mesma coisa com código síncrono. Não precisamos salvar o link manualmente porque .putSync()
salva automaticamente todos os links. Até cria o professor para nós.
final englishTeacher = Teacher()..subject = 'English';
final david = Student()
..name = 'David'
..teacher.value = englishTeacher;
isar.writeTxnSync(() {
isar.students.putSync(david);
});
IsarLinks
Faria mais sentido se o aluno do exemplo anterior pudesse ter vários professores. Felizmente, Isar tem IsarLinks<T>
, que pode conter vários objetos relacionados e expressar um relacionamento para muitos.
IsarLinks<T>
estende Set<T>
e expõe todos os métodos permitidos para sets.
IsarLinks
se comporta muito como IsarLink
e também é preguiçoso. Para carregar todos os objetos vinculados, chame linkProperty.load()
. Para persistir as alterações, chame linkProperty.save()
.
Internamente, IsarLink
e IsarLinks
são representados da mesma maneira. Podemos atualizar o IsarLink<Teacher>
de antes para um IsarLinks<Teacher>
para atribuir vários professores a um único aluno (sem perder dados).
@collection
class Student {
late int id;
late String name;
final teachers = IsarLinks<Teacher>();
}
Isso funciona porque não mudamos o nome do link (professor
), então Isar se lembra de antes.
final biologyTeacher = Teacher()..subject = 'Biology';
final linda = isar.students.where()
.filter()
.nameEqualTo('Linda')
.findFirst();
print(linda.teachers); // {Teacher('Math')}
linda.teachers.add(biologyTeacher);
await isar.writeAsync((isar) async {
await linda.teachers.save();
});
print(linda.teachers); // {Teacher('Math'), Teacher('Biology')}
Backlinks
Eu ouço você perguntar: "E se quisermos expressar relacionamentos reversos?". Não se preocupe; agora vamos apresentar backlinks.
Backlinks são links na direção inversa. Cada link sempre tem um backlink implícito. Você pode disponibilizá-lo para seu aplicativo anotando um IsarLink
ou IsarLinks
com @Backlink()
.
Backlinks não requerem memória ou recursos adicionais; você pode adicionar, remover e renomeá-los livremente sem perder dados.
Queremos saber quais students um teacher específico tem, então definimos um backlink:
@collection
class Teacher {
Id id;
late String subject;
@Backlink(to: 'teacher')
final student = IsarLinks<Student>();
}
Precisamos especificar o link para o qual o backlink aponta. É possível ter vários links diferentes entre dois objetos.
Inicializar links
IsarLink
e IsarLinks
possuem um construtor sem argumentos, que deve ser usado para atribuir a propriedade link quando o objeto for criado. É uma boa prática tornar as propriedades do link final
.
Quando você faz o put()
do seu objeto pela primeira vez, o link é inicializado com a coleção de origem e destino, e você pode chamar métodos como load()
e save()
. Um link começa a rastrear as alterações imediatamente após sua criação, para que você possa adicionar e remover relações antes mesmo de o link ser inicializado.
Perigo
É ilegal mover um link para outro objeto.