Вместо привязки я бы использовал виртуальный режим. Это позволяет довольно легко получать данные на лету из разных источников. У Microsoft есть руководство по его использованию: Как: реализовать виртуальный режим в элементе управления Windows Forms DataGridView
По сути, вместо загрузки всех данных при запуске или использования источника привязки вы перехватываете событие CellValueNeeded. DataGridView будет запускать это событие всякий раз, когда ему нужно отобразить ячейку, и вы можете предоставить любые данные, которые вы хотите в это время. В своем обработчике CellValueNeeded вы можете сопоставить строку и столбец DataGridView с вашими таблицами так, как вам нравится.
private void my_init_function() {
datagridview.VirtualMode = true;
datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded);
}
private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
e.Value = get_my_data(e.RowIndex, e.ColumnIndex);
}