Create database relationships between the link node dataset and the channel input file.

        The link node dataset only stores references to the links and nodes--not the geometry. The link and node
        geometries are stored in the channel input file. The two files must be linked with database relationships to
        allow the creation of link node dataset visualizations.

        This process is not performed automatically during reading, because it can be very costly in terms of read time.
        This operation can only be performed after both files have been read into the database.

        Args:
            session (:mod:`sqlalchemy.orm.session.Session`): SQLAlchemy session object bound to PostGIS enabled database
            channelInputFile (:class:`gsshapy.orm.ChannelInputFile`): Channel input file object to be associated with
                this link node dataset file.
            force (bool, optional): Force channel input file reassignment. When false (default), channel input file
                assignment is skipped if it has already been performed.

def linkToChannelInputFile(self, session, channelInputFile, force=False):
        """
        Create database relationships between the link node dataset and the channel input file.

        The link node dataset only stores references to the links and nodes--not the geometry. The link and node
        geometries are stored in the channel input file. The two files must be linked with database relationships to
        allow the creation of link node dataset visualizations.

        This process is not performed automatically during reading, because it can be very costly in terms of read time.
        This operation can only be performed after both files have been read into the database.

        Args:
            session (:mod:`sqlalchemy.orm.session.Session`): SQLAlchemy session object bound to PostGIS enabled database
            channelInputFile (:class:`gsshapy.orm.ChannelInputFile`): Channel input file object to be associated with
                this link node dataset file.
            force (bool, optional): Force channel input file reassignment. When false (default), channel input file
                assignment is skipped if it has already been performed.
        """

        # Only perform operation if the channel input file has not been assigned or the force parameter is true
        if self.channelInputFile is not None and not force:
            return

        # Set the channel input file relationship
        self.channelInputFile = channelInputFile

        # Retrieve the fluvial stream links
        orderedLinks = channelInputFile.getOrderedLinks(session)

        # Retrieve the LinkNodeTimeStep objects
        timeSteps = self.timeSteps

        # Link each link dataset in each time step
        for timeStep in timeSteps:
            # Retrieve link datasets
            linkDatasets = timeStep.linkDatasets

            # Link each node dataset
            for l, linkDataset in enumerate(linkDatasets):
                # Get the fluvial link and nodes
                streamLink = orderedLinks[l]
                streamNodes = streamLink.nodes

                # Link link datasets to fluvial links
                linkDataset.link = streamLink

                # Retrieve node datasets
                nodeDatasets = linkDataset.nodeDatasets

                # Link the node dataset with the channel input file nodes
                if len(nodeDatasets) > 0 and len(streamNodes) > 0:
                    for n, nodeDataset in enumerate(nodeDatasets):
                        nodeDataset.node = streamNodes[n]

        session.add(self)
        session.commit()