Опция 1 :
Если база данных, в которой хранится информация о состоянии, не постоянно обновляется каким-либо другим процессом, вы можете просто указать, что столбец для объединения является частью таблицы во внешней базе данных.
Если вместо этого он получает обновления из других источников, вам придется опрашивать его с помощью таймера (или использовать класс FileSystemWatcher для получения уведомлений при изменении файла базы данных). Запрос такой же, хотя.
Добавьте [;database=Second database Path].[Source Table] AS alias
после предложения JOIN, затем продолжайте как обычно.
Например, установите DataGridView.Datasource, указав второй путь к базе данных.
LogDataGridView.DataSource = GetCrossJoinedTable([Second database path]);
Строка подключения Data Source=
содержит путь к первой базе данных.
Затем выполните перекрестное соединение двух таблиц в двух базах данных, используя общий ключ, и верните столбец, содержащий информацию о состоянии. из таблицы во второй базе данных (столбец [Order Status]
, если я правильно прочитал обновленный код).
private DataTable GetCrossJoinedTable(string secondDataBasePath)
{
var dt = new DataTable("JoinedTable");
string sql = "SELECT [Data].*, status.[Order Status] " +
$"FROM [Data] LEFT JOIN [;database={secondDataBasePath}].[Output] AS status " +
"ON [Data].[SO nr] = status.[Source No]";
using (var connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=firstDatabase.accdb;Persist Security Info=false;"))
using (var command = new OleDbCommand(sql, connection)) {
connection.Open();
var reader = command.ExecuteReader();
dt.Load(reader);
return dt;
}
}
Опция 2 :
Запросить первую базу данных, добавить столбец состояния, обновить информацию о состоянии из второй базы данных, а затем опросить новую информацию о состоянии с помощью таймера.
Вы можете позвонить LogDataGridView.DataSource = GetMainTableData()
, чтобы установить источник данных. Он также загрузит информацию о состоянии из второй базы данных.
Затем таймер будет опрашивать только вторую базу данных, чтобы проверить, изменился ли [Order Status]
соответствующего столбца [SO nr]
в DataTable.
Когда DataTable (здесь, поле с именем * 1034) *) обновляется, ваш DataGraidView немедленно отразит изменение.
- Если данные можно редактировать, таймер должен пропустить обновление, если IsCurrentCellInEditMode вернет
true
(прочитайте заметки там о CheckBoxColumns) или остановится, пока ячейка в режиме редактирования ( CellBeginEdit событие) и возобновляется при выходе ячейки из режима редактирования ( CellEndEdit событие). - Не забудьте останавливать и утилизировать таймер при закрытии формы (событие
Form.FormClosing
).
Если вам не нужен таймер для опроса информации о состоянии, просто звоните UpdateStatusInfo()
всякий раз, когда вам нужно обновить DGV.
System.Windows.Forms.Timer sqlTimer = null;
DataTable mainDT = new DataTable("MainTable");
private DataTable GetMainTableData()
{
string sql = "SELECT * FROM Data";
using (var connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=firstDatabase.accdb;Persist Security Info=false;"))
using (var command = new OleDbCommand(sql, connection)) {
connection.Open();
var reader = command.ExecuteReader();
mainDT.Load(reader);
mainDT.Columns.Add(new DataColumn() {
Caption = "Status", ColumnName = "fStatus", DataType = typeof(string), ReadOnly = true
});
}
sqlTimer = new System.Windows.Forms.Timer() { Interval = 5000 };
sqlTimer.Tick += (s, ev) => { UpdateStatusInfo(mainDT, false); };
sqlTimer.Start();
return UpdateStatusInfo(mainDT, true);
}
private DataTable UpdateStatusInfo(DataTable dt, bool returnTable)
{
string sql = "SELECT Output.[Order Status], Output.[Source No] FROM Output";
using (var connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=secondDatabase.accdb;Persist Security Info=false;"))
using (var command = new OleDbCommand(sql, connection)) {
connection.Open();
var reader = command.ExecuteReader();
dt.Columns["fStatus"].ReadOnly = false;
while (reader.Read()) {
dt.Select($"fNumber = {reader["Source No"]}").FirstOrDefault()?
.SetField("fStatus", reader["Order Status"].ToString());
}
dt.Columns["fStatus"].ReadOnly = true;
return returnTable ? dt : null;
}
}