Qual è il modo migliore per creare un oggetto DataTable vuoto con lo schema di una tabella di SQL Server?necessità di ottenere DataTable vuoto in .NET con la tabella del database schema
risposta
Una dichiarazione che penso è degno di nota è SET FMTONLY:
SET FMTONLY ON;
SELECT * FROM SomeTable
SET FMTONLY OFF;
Nessuna riga vengono elaborati o inviati al client a causa della richiesta al momento SET FMTONLY è acceso.
Il motivo per cui questo può essere utile è perché è possibile fornire qualsiasi query/stored procedure e restituire solo i metadati del gruppo di risultati.
Partendo dal presupposto che è possibile connettersi al database SQL che contiene la tabella che si desidera copiare nel punto che ora si vuole fare questo, è possibile utilizzare un gruppo di risultati convenzionale per la conversione DataTable, utilizzando
select * from <tablename> where 1=2
come la tua query di origine.
Ciò restituirà un risultato vuoto impostato con la struttura della tabella di origine.
Prova: SELECT TOP 0 * FROM [TableName]
e utilizzare SqlDataAdapter per riempire un DataSet, quindi ottenere la tabella da quella DataSet.
È sempre possibile creare il proprio:
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 tirarsi indietro è che si dovrà aggiornare il codice ogni volta che lo schema del database modifiche.
Ecco quello che 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.
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
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
Tutte queste soluzioni sono corrette, ma se si desidera una soluzione di codice puro che viene semplificato per questo scenario.
dati viene restituito in questa soluzione in quanto CommandBehavior.SchemaOnly è specificato sulla funzione ExecuteReader (Command Behavior Documentation)
La soluzione CommandBehavior.SchemaOnly aggiungerà il 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;
}
piace questo, funziona su tutti i database;) – AsG