The Microsoft KB example code or class library documentation do not explain how to efficiently return a table’s schema. For example, this code follows the documentation:
DataTable dataTable = null;
using (IDbConnection dbConnection = (IDbConnection)database.Unwrap()) {
dbConnection.Open();
using (IDbCommand dbCommand = dbConnection.CreateCommand()) {
dbCommand.CommandType = CommandType.Text;
dbCommand.CommandText = "SELECT * FROM SomeLargeTable;";
using (IDataReader dataReader = dbCommand.ExecuteReader(CommandBehavior.KeyInfo)) {
dataTable = dataReader.GetSchemaTable();
dataReader.Close();
}
}
dbConnection.Close();
}
// look at table schema stored in dataTable
Results in the following SQL executed on Sql Server:
SET FMTONLY OFF; SET NO_BROWSETABLE ON;
SELECT * FROM SomeLargeTable; SET NO_BROWSETABLE OFF;
If you add | CommandBehavior.SchemaOnly
to the ExecuteReader method call:
SET FMTONLY OFF; SET NO_BROWSETABLE ON; SET FMTONLY ON;
SELECT * FROM SomeLargeTable; SET NO_BROWSETABLE OFF; SET FMTONLY OFF;
According to the documentation:
CommandBehavior.SchemaOnly Link to heading
The query returns column information only. When using SchemaOnly, the .NET Framework Data Provider for SQL Server precedes the statement being executed with SET FMTONLY ON. — .NET Docs1
FMTONLY ON Link to heading
Returns only metadata to the client. Can be used to test the format of the response without actually running the query. — SQL Docs2
As expected, I had a significant preformance increase With (CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly)
. Querying 100,000,000 rows to retrieve table schema is inefficent, to say the least.