private function createRelationship(
        Identity $identity,
        object $entity,
        Query $query
    ): Query {
        $meta = ($this->metadata)(\get_class($entity));
        $data = ($this->extract)($entity);
        $start = $data->get($meta->startNode()->property());
        $end = $data->get($meta->endNode()->property());
        $varName = $this->name->sprintf(\md5($identity->value()));
        $startName = $this->name->sprintf(\md5($start));
        $endName = $this->name->sprintf(\md5($end));

        $paramKey = $varName->append('_props');
        $properties = $this->buildProperties($meta->properties(), $paramKey);
        $keysToKeep = $data->keys()->intersect($properties->keys());

        return $this
            ->matchEdge(
                $endName,
                $meta->endNode(),
                $end,
                $this->matchEdge(
                    $startName,
                    $meta->startNode(),
                    $start,
                    $query
                )
            )
            ->create((string) $startName)
            ->linkedTo((string) $endName)
            ->through(
                (string) $meta->type(),
                (string) $varName,
                'right'
            )
            ->withProperty(
                $meta->identity()->property(),
                (string) $paramKey
                    ->prepend('{')
                    ->append('}.')
                    ->append($meta->identity()->property())
            )
            ->withProperties($properties->reduce(
                [],
                static function(array $carry, string $property, string $cypher): array {
                    $carry[$property] = $cypher;

                    return $carry;
                }
            ))
            ->withParameter(
                (string) $paramKey,
                $data
                    ->filter(static function(string $key) use ($keysToKeep): bool {
                        return $keysToKeep->contains($key);
                    })
                    ->put($meta->identity()->property(), $identity->value())
                    ->reduce(
                        [],
                        static function(array $carry, string $key, $value): array {
                            $carry[$key] = $value;

                            return $carry;
                        }
                    )
            );
    }