È necessario ottenere datatable in .net con lo schema della tabella del database

Qual è il modo migliore per creare un object DataTable vuoto con lo schema di una tabella sql server?

Una frase che penso valga la pena di menzionare SET FMTONLY :

SET FMTONLY ON; SELECT * FROM SomeTable SET FMTONLY OFF; 

Nessuna riga viene elaborata o inviata al client a causa della richiesta quando SET FMTONLY è triggersto.

Il motivo per cui questo può essere utile è che è ansible fornire qualsiasi query / stored procedure e restituire solo i metadati del set di risultati.

Tutte queste soluzioni sono corrette, ma se si desidera una soluzione di codice pura che sia ottimizzata per questo scenario.

Nessun dato viene restituito in questa soluzione poiché CommandBehavior.SchemaOnly è specificato sulla funzione ExecuteReader ( Command Behavior Documentation )

La soluzione CommandBehavior.SchemaOnly aggiungerà SET FMTONLY ON; SQL prima che la query sia eseguita per te, mantiene pulito il tuo codice.

 public static DataTable GetDataTableSchemaFromTable(string tableName, SqlConnection sqlConn, SqlTransaction transaction) { DataTable dtResult = new DataTable(); using (SqlCommand command = sqlConn.CreateCommand()) { command.CommandText = String.Format("SELECT TOP 1 * FROM {0}", tableName); command.CommandType = CommandType.Text; if (transaction != null) { command.Transaction = transaction; } SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly); dtResult.Load(reader); } return dtResult; } 

Prova: SELECT TOP 0 * FROM [TableName]

e utilizzare SQLDataAdapter per riempire un DataSet, quindi ottenere la tabella da quel DataSet.

Supponendo che sia ansible connettersi al database SQL che contiene la tabella che si desidera copiare nel momento in cui si desidera eseguire questa operazione, è ansible utilizzare un resultset convenzionale per la conversione datatable, utilizzando

 select * from  where 1=2 

come la tua query di origine.

Ciò restituirà un set di risultati vuoto con la struttura della tabella di origine.

Ecco cosa ho fatto:

 var conn = new SqlConnection("someConnString"); var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM MyTable; SET FMTONLY OFF;",conn); var dt = new DataTable(); conn.Open(); dt.Load(cmd.ExecuteReader()); conn.Dispose(); 

Funziona bene. Grazie AdaTheDev.

 Class BlankTableWithSourceTableSchema Inherits DataTable Public Sub New(ByVal connstr As String, ByVal sourcetable As String) Try Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr) Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection) adapter.TableMappings.Add("Table", "ABlankTable") adapter.FillSchema(Me, SchemaType.Mapped) End Using Catch ex As Exception End Try End Sub End Class 

questo funziona:

 Class BlankTableWithSourceTableSchema Inherits DataTable Public Sub New(ByVal connstr As String, ByVal sourcetable As String) Try Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr) Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection) adapter.TableMappings.Add("Table", "ABlankTable") adapter.FillSchema(Me, SchemaType.Mapped) End Using Catch ex As Exception End Try End Sub End Class 

So che questa è una vecchia domanda e specifica per SQL Server. Ma se stai cercando una soluzione generica che funzioni su diversi database, usa la soluzione di Richard, ma modificala per usare "SELECT * FROM {0} WHERE 1=0" e cambia i tipi per usare i tipi ADO.Net generici IDataReader, IDbCommand eccetera.

La maggior parte dei moderni database relazionali è abbastanza intelligente da identificare la condizione 1 = 0 e non la eseguirà come una normale query tablescan. Ho provato questo su SQL Server, Oracle e DB2 con tabelle hanno anche alcuni 100 milioni di record. Tutti restituiscono il risultato vuoto in pochi millisecondi.

Puoi sempre creare il tuo:

  DataTable table = new DataTable("TableName"); table.Columns.Add(new DataColumn("Col1", typeof(int))); table.Columns.Add(new DataColumn("Col2", typeof(int))); table.Columns.Add(new DataColumn("Col3", typeof(string))); table.Columns.Add(new DataColumn("Col4", typeof(int))); table.Columns.Add(new DataColumn("Col5", typeof(string))); 

L’ovvio inconveniente è che dovrai aggiornare il tuo codice ogni volta che lo schema del database cambia.