Проблема в том, что Access (или JET Red) не имеет единого канонического API для работы с его моделью данных, вместо этого вы в основном используете драйвер OLE-DB или драйвер ODBC.Я думаю (но не могу подтвердить), что программа графического интерфейса Office Access , вероятно, имеет собственный внутренний API, который обходит абстракции OLE-DB или ODBC, к сожалению, программа GUI не использует специальную техническую терминологию в таких вещах, как конструктор таблиц(например, Number > Integer
не говорит, является ли оно 16-, 32- или 64-разрядным целым числом, а Number > Replication ID
вовсе не числом, а GUID Win32).
По состоянию на 2019 год Microsoft, по-видимому, с приоритетом OLE-DB по сравнению с API-интерфейсом ODBC более низкого уровня для JET Red, но это нормально, потому что ODBC по-прежнему предоставляет нам необходимую информацию для определения структуры таблицы базы данных.
В любом случае -Хорошей новостью является то, что вам не обязательно нужен инструмент для сравнения базы данных Access (JET Red) с базой данных SQL Server, потому что легко получить спецификации таблицы ODBC самостоятельно.
Примерно так:
Dictionary<String,DataTable> jetTables = new Dictionary<String,DataTable>();
using( OleDbConnection jetConnection = new OleDbConnection( "your-access-connection-string") )
{
await jetConnection.OpenAsync().ConfigureAwait(false);
DataTable schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" }
);
foreach( DataRow row in schemaTable.Rows.Cast<DataRow>() )
{
String tableName = (String)row.ItemArray[2];
DataTable tableSchema = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new object[] { null, null, tableName, "TABLE" }
);
jetTables.Add( tableName, tableSchema );
}
}
Dictionary<String,DataTable> sqlTables = new Dictionary<String,DataTable>();
using( SqlConnection sqlConnection = new SqlConnection( "your-sql-server-connection-string" ) )
{
await sqlConnection.OpenAsync().ConfigureAwait(false);
DataTable allTables = new DataTable();
using( SqlCommand cmd1 = sqlConnection.CreateCommand() )
{
cmd1.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
using( SqlDataReader rdr1 = await cmd1.ExecuteReaderAsync.ConfigureAwait(false) )
{
allTables.Load( rdr1 );
}
}
foreach( DataRow row in allTables.Rows.Cast<DataRow>() )
{
String tableName = (String)row.ItemArray[0];
using( SqlCommand cmd2 = sqlConnection.CreateCommand() )
{
cmd2.CommandText = "SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName";
cmd2.Parameters.Add( "@tableName", SqlDbType.NVarChar ).Value = tableName;
using( SqlDataReader rdr2 = await cmd2.ExecuteReaderAsync.ConfigureAwait(false) )
{
DataTable dt = new DataTable();
dt.Load( rdr2 );
sqlTables.Add( tableName, dt );
}
}
}
}
Затем сравните jetTables
с sqlTables
, как вам угодно.