loadReferences<C, P> method
Future<Map<EntityEntry<C> , P?> >
loadReferences<C, P>(
- ForeignKey<
C, P> relation, - Iterable<
EntityEntry< childrenC> >
Loads parents for children in batches.
Implementation
Future<Map<EntityEntry<C>, P?>> loadReferences<C, P>(
ForeignKey<C, P> relation, Iterable<EntityEntry<C>> children) {
final entries = List<EntityEntry<C>>.of(children);
_checkRegisteredRelationship(this, relation);
for (final entry in entries) {
_checkRelationshipEntry(entry, relation.child);
if (!identical(entry.context, this)) {
throw const OrmStateException(
'Relationship entries belong to different contexts');
}
}
return _serialize(() async {
final result = Map<EntityEntry<C>, P?>.identity();
final wanted = <EntityKey, List<EntityEntry<C>>>{};
for (final entry in entries) {
_checkRelationshipEntry(entry, relation.child);
final links = _relationshipLinks[entry];
if (links != null && links.containsKey(relation)) {
_validateRelationshipLinks(entry);
final parent = links[relation];
if (parent != null) {
_checkRelationshipEntry(parent, relation.parent);
}
result[entry] = parent?.entity as P?;
continue;
}
final key = _relationshipEntityKey(relation.columns, entry.entity);
if (key == null) {
result[entry] = null;
} else {
(wanted[key] ??= []).add(entry);
}
}
final parents = <EntityKey, P>{};
for (final chunk
in _relationshipChunks(wanted.keys, relation.targetColumns.length)) {
final predicate = _relationshipPredicate(relation.targetColumns, chunk);
final rows = await connection.query(
'SELECT ${_relationshipProjection(relation.parent)} '
'FROM ${quoteIdentifier(relation.parent.tableName)} '
'WHERE ${predicate.$1}',
predicate.$2);
for (final values in rows.rows) {
final reader = _relationshipReader(rows.columns, values);
final key = _relationshipReaderKey(relation.targetColumns, reader);
if (key == null || parents.containsKey(key)) {
throw const OrmStateException(
'Relationship target is not unique in the store');
}
parents[key] = _materialize(relation.parent, reader);
}
}
final required = relation.columns.every((column) => !column.nullable);
for (final request in wanted.entries) {
final parent = parents[request.key];
if (parent == null && required) {
throw OrmStateException(
'Required parent for ${relation.name} is missing');
}
for (final entry in request.value) {
result[entry] = parent;
}
}
return Map<EntityEntry<C>, P?>.unmodifiable(result);
});
}